summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfvogel <fvogel@noemail.net>2016-05-03 17:24:52 (GMT)
committerfvogel <fvogel@noemail.net>2016-05-03 17:24:52 (GMT)
commit66e049facdcbb1af14fec0618f6e8499871ff2d7 (patch)
tree66d0ca9d971be9925bbc17c61534b9430d8fdf22
parent351686ad0aa39242af9d6d1da4a960f1f910ad50 (diff)
parentdc9ab33a6b593607de9b90e1b975177ad0381ac8 (diff)
downloadtk-66e049facdcbb1af14fec0618f6e8499871ff2d7.zip
tk-66e049facdcbb1af14fec0618f6e8499871ff2d7.tar.gz
tk-66e049facdcbb1af14fec0618f6e8499871ff2d7.tar.bz2
Fixed [011706ec42] - tk::ButtonInvoke safety bug
FossilOrigin-Name: e1431c56fe45233411560153a8c52facd25b46fa
-rw-r--r--library/button.tcl19
-rw-r--r--tests/button.test18
2 files changed, 34 insertions, 3 deletions
diff --git a/library/button.tcl b/library/button.tcl
index b2bafb2..80d8bf9 100644
--- a/library/button.tcl
+++ b/library/button.tcl
@@ -597,12 +597,25 @@ 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
+ after 100 [list ::tk::ButtonInvokeEnd $w $oldState $oldRelief]
+ }
+}
+
+# ::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.
+# oldState - Old state to be set back.
+# oldRelief - Old relief to be set back.
+
+proc ::tk::ButtonInvokeEnd {w oldState oldRelief} {
+ if {[winfo exists $w]} {
$w configure -state $oldState -relief $oldRelief
uplevel #0 [list $w invoke]
}
diff --git a/tests/button.test b/tests/button.test
index d28559a..28d8934 100644
--- a/tests/button.test
+++ b/tests/button.test
@@ -3908,6 +3908,24 @@ 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
+ }
+ }
+ toplevel .top
+ button .top.b -text Foo -command destroy_button
+ bind .top.b <space> destroy_button
+ pack .top.b
+ focus -force .top.b
+ update
+ event generate .top.b <space>
+ update ; # shall not trigger error invalid command name ".top.b"
+} -cleanup {
+ destroy .top.b .top
+} -result {}
+
imageFinish
cleanupTests
return