Subject: | Crashes due to grab failure in the Menu & Menubutton |
Hi All,
Our Perl/Tk application sometimes crashes with
these messages:
Tk::Error: grab failed: window not viewable at /usr/lib/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi/Tk/Submethods.pm line 19.
Tk callback for grab
Tk::Submethods::__ANON__ at /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi/Tk/Submethods.pm line 19
Tk::Menu::ButtonDown at /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi/Tk/Menu.pm line 439
<Button>
(command bound to event)
Googling with the 'perl tk grab submethods' query
brings the tip:
Show quoted text
> It looks to me like Menubutton is doing a grab and not protecting against
> failure. At the end of the Post method in Menubutton.pm the is the line:
>
> $w->grabGlobal;
>
> One could change the line to:
>
> Tk::catch{$w->grabGlobal};
>
> --
> Marc Dashevsky (remove "_" from address to reply by e-mail)
However the method doesn't look as a good solution (it's not
succeed with the grab). Anyway I've just followed it in order to avoid
application crashes (I changed grab calls in both Menu.pm & Menubutton.pm).
It was enough to fix these crashes in our application.
See my patch in the attached file.
Although I'm sure there are more intelligent solutions for the problem...
Best regards,
Dmitry Samborskiy
--- ./Menubutton/Menubutton.pm.orig
+++ ./Menubutton/Menubutton.pm
@@ -270,7 +270,8 @@
{
$menu->focus;
$w->SaveGrabInfo;
- $w->grabGlobal;
+# $w->grabGlobal;
+ Tk::catch{$w->grabGlobal};
}
}
# Motion --
--- ./Tk/Menu.pm.orig
+++ ./Tk/Menu.pm
@@ -406,7 +406,8 @@
$menu->postcascade('active');
if (defined $Tk::postedMb)
{
- $Tk::postedMb->grabGlobal
+# $Tk::postedMb->grabGlobal
+ Tk::catch{$Tk::postedMb->grabGlobal};
}
else
{
@@ -435,7 +436,8 @@
# Must re-grab even if the grab window hasn't changed, in order
# to release the implicit grab from the button press.
- $menu->grabGlobal if ($Tk::platform eq 'unix');
+# $menu->grabGlobal if ($Tk::platform eq 'unix');
+ Tk::catch{$menu->grabGlobal} if ($Tk::platform eq 'unix');
}
}
@@ -891,7 +893,8 @@
my $entry = shift;
Unpost(undef) if (defined($Tk::popup) || defined($Tk::postedMb));
$menu->PostOverPoint($x,$y,$entry);
- $menu->grabGlobal;
+# $menu->grabGlobal;
+ Tk::catch{$menu->grabGlobal};
$Tk::popup = $menu;
$Tk::focus = $menu->focusCurrent;
$menu->focus();