diff --git a/t/GtkMenu.t b/t/GtkMenu.t
index 61e7daa..a96029d 100644
--- a/t/GtkMenu.t
+++ b/t/GtkMenu.t
@@ -8,7 +8,7 @@
 # 	- rm
 #########################
 
-use Gtk2::TestHelper tests => 61;
+use Gtk2::TestHelper tests => 63;
 
 ok( my $menubar = Gtk2::MenuBar->new );
 
@@ -156,6 +156,23 @@ unless ($i_know_you) {
 	}
 }
 
+{
+  my $popup_runs = 0;
+  my $saw_warning = '';
+  { local $SIG{__WARN__} = sub { $saw_warning = $_[0] };
+    $menu->popup(undef, undef, sub {
+                   $popup_runs = 1;
+                   die;
+                 }, undef, 1, 0);
+  }
+  diag "popup position runs=$popup_runs warn='$saw_warning'";
+  $menu->popdown;
+  ok ($popup_runs,
+      'popup positioning die() - popup runs');
+  ok ($saw_warning,
+      'popup positioning die() - die not fatal, turned into warning');
+}
+
 SKIP: {
 	skip 'new 2.14 stuff', 2
 		unless Gtk2->CHECK_VERSION(2, 14, 0);
diff --git a/xs/GtkMenu.xs b/xs/GtkMenu.xs
index a738af7..4a01175 100644
--- a/xs/GtkMenu.xs
+++ b/xs/GtkMenu.xs
@@ -57,24 +57,34 @@ gtk2perl_menu_position_func (GtkMenu * menu,
 	if (callback->data)
 		XPUSHs (sv_2mortal (newSVsv (callback->data)));
 
-	PUTBACK;
-
-	n = call_sv (callback->func, G_ARRAY);
+	/* A die() from callback->func is suspected to be bad or very bad.
+	   Circa Gtk 2.18 a jump out of $menu->popup seems to leave an X
+	   grab with no way to get rid of it (no keyboard Esc, and no mouse
+	   click handlers).  The position func can also be called later for
+	   things like resizing or move to a different GdkScreen, and such a
+	   call might come straight from the main loop, where a die() would
+	   jump out of Gtk2->main.  */
 
+	PUTBACK;
+	n = call_sv (callback->func, G_ARRAY | G_EVAL);
 	SPAGAIN;
 
-	if (n < 2 || n > 3)
-		croak ("menu position callback must return two integers "
-		       "(x, and y) or two integers and a boolean (x, y, and "
-		       "push_in)");
-
-	/* POPs and POPi take things off the *end* of the stack! */
-	if (n > 2) {
-		SV *sv = POPs;
-		*push_in = sv_2bool (sv);
+	if (SvTRUE (ERRSV)) {
+		g_warning ("menu position callback ignoring error: %s",
+			   SvPVutf8_nolen (ERRSV));
+	} else if (n < 2 || n > 3) {
+		g_warning ("menu position callback must return two integers "
+			   "(x, and y) or two integers and a boolean "
+			   "(x, y, and push_in)");
+	} else {
+		/* POPs and POPi take things off the *end* of the stack! */
+		if (n > 2) {
+			SV *sv = POPs;
+			*push_in = sv_2bool (sv);
+		}
+		if (n > 1) *y = POPi;
+		if (n > 0) *x = POPi;
 	}
-	if (n > 1) *y = POPi;
-	if (n > 0) *x = POPi;
 
 	PUTBACK;
 	FREETMPS;
