From fe445933c38a59e269197da7ad01187157358ab4 Mon Sep 17 00:00:00 2001 From: fvogel Date: Fri, 29 Apr 2016 19:07:53 +0000 Subject: Fixed [011706ec42] - tk::ButtonInvoke safety bug --- library/button.tcl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/library/button.tcl b/library/button.tcl index b2bafb2..061069a 100644 --- a/library/button.tcl +++ b/library/button.tcl @@ -597,14 +597,16 @@ proc ::tk::ButtonUp w { # w - The name of the widget. proc ::tk::ButtonInvoke w { - if {[$w cget -state] ne "disabled"} { + if {[winfo exists $w] && [$w cget -state] ne "disabled"} { set oldRelief [$w cget -relief] set oldState [$w cget -state] $w configure -state active -relief sunken update idletasks after 100 - $w configure -state $oldState -relief $oldRelief - uplevel #0 [list $w invoke] + if {[winfo exists $w]} { + $w configure -state $oldState -relief $oldRelief + uplevel #0 [list $w invoke] + } } } -- cgit v0.12 From dd7c680bf0627dc809b4b205ad1258100deaa466 Mon Sep 17 00:00:00 2001 From: fvogel Date: Fri, 29 Apr 2016 19:23:56 +0000 Subject: Fixed indentation --- library/button.tcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/button.tcl b/library/button.tcl index 061069a..16624e7 100644 --- a/library/button.tcl +++ b/library/button.tcl @@ -604,8 +604,8 @@ proc ::tk::ButtonInvoke w { update idletasks after 100 if {[winfo exists $w]} { - $w configure -state $oldState -relief $oldRelief - uplevel #0 [list $w invoke] + $w configure -state $oldState -relief $oldRelief + uplevel #0 [list $w invoke] } } } -- cgit v0.12 From acdaf387562f63cecd2e448c4790aa5e02bd89a9 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 30 Apr 2016 15:50:35 +0000 Subject: Experiment: can it be done without a busy wait as well? Not tested on all platforms yet, feedback appreciated! --- library/button.tcl | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/library/button.tcl b/library/button.tcl index 16624e7..469a9a8 100644 --- a/library/button.tcl +++ b/library/button.tcl @@ -589,6 +589,20 @@ proc ::tk::ButtonUp w { # Shared routines ################## +# ::tk::ButtonInvokeEnd -- +# The procedure below is called after a button is invoked through +# the keyboard. It simulate a release of the button via the mouse. +# +# Arguments: +# w - The name of the widget. + +proc ::tk::ButtonInvokeEnd {w oldState oldRelief} { + if {[winfo exists $w]} { + $w configure -state $oldState -relief $oldRelief + uplevel #0 [list $w invoke] + } +} + # ::tk::ButtonInvoke -- # The procedure below is called when a button is invoked through # the keyboard. It simulate a press of the button via the mouse. @@ -601,12 +615,7 @@ proc ::tk::ButtonInvoke w { set oldRelief [$w cget -relief] set oldState [$w cget -state] $w configure -state active -relief sunken - update idletasks - after 100 - if {[winfo exists $w]} { - $w configure -state $oldState -relief $oldRelief - uplevel #0 [list $w invoke] - } + after 100 [list ::tk::ButtonInvokeEnd $w $oldState $oldRelief] } } -- cgit v0.12 From 9685eae702c2d72291bb0b47e5ec481b9afa3a80 Mon Sep 17 00:00:00 2001 From: fvogel Date: Mon, 2 May 2016 20:45:41 +0000 Subject: Added test button-14.1 to guard against regressions regarding [011706ec42] --- tests/button.test | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/button.test b/tests/button.test index 6d924f6..05f463c 100644 --- a/tests/button.test +++ b/tests/button.test @@ -3908,6 +3908,25 @@ test button-13.8 {size behavior: checkbutton} -setup { destroy .a .b .c } -result {1 1 1} +test button-14.1 {bug fix: [011706ec42] tk::ButtonInvoke unsafe wrt widget destruction} -body { + proc destroy_button {} { + if {[winfo exists .top.b]} { + destroy .top.b + puts destroyed + } + } + toplevel .top + button .top.b -text Foo -command destroy_button + bind .top.b destroy_button + pack .top.b + focus -force .top.b + update + event generate .top.b + update ; # shall not trigger error invalid command name ".top.b" +} -cleanup { + destroy .top.b .top +} -result {} + imageFinish cleanupTests return -- cgit v0.12