summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/tcltklib/tcltklib.c2
-rw-r--r--ext/tk/lib/tk.rb31
-rw-r--r--ext/tk/lib/tkafter.rb3
-rw-r--r--ext/tk/sample/safe-tk.rb9
4 files changed, 32 insertions, 13 deletions
diff --git a/ext/tcltklib/tcltklib.c b/ext/tcltklib/tcltklib.c
index 12629a423e..ec00cea217 100644
--- a/ext/tcltklib/tcltklib.c
+++ b/ext/tcltklib/tcltklib.c
@@ -1020,7 +1020,7 @@ ip_invoke_real(argc, argv, obj)
/* exception on mainloop */
if (ptr->return_value == TCL_ERROR) {
- if (event_loop_abort_on_exc > 0) {
+ if (event_loop_abort_on_exc > 0 && !Tcl_InterpDeleted(ptr->ip)) {
rb_raise(rb_eRuntimeError, "%s", ptr->ip->result);
} else {
if (event_loop_abort_on_exc < 0) {
diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb
index 6ee5c36fba..13e41ece44 100644
--- a/ext/tk/lib/tk.rb
+++ b/ext/tk/lib/tk.rb
@@ -3359,7 +3359,7 @@ class TkObject<TkKernel
private :tk_trace_variable
def destroy
- tk_call 'trace', 'vdelete', @tk_vn, 'w', @var_id if defined? @var_id
+ # tk_call 'trace', 'vdelete', @tk_vn, 'w', @var_id if @var_id
end
end
@@ -3721,10 +3721,21 @@ class TkWindow<TkObject
self
end
+ def _destroy_children
+ children = []
+ rexp = /^#{self.path}\.[^.]+$/
+ TkCore::INTERP.tk_windows.each{|path, obj|
+ children << obj if path =~ rexp
+ }
+ children.each{|obj| obj.destroy}
+ end
+ private :_destroy_children
+
def destroy
super
+ _destroy_children
tk_call 'destroy', epath
- if @cmdtbl
+ if defined?(@cmdtbl)
for id in @cmdtbl
uninstall_cmd id
end
@@ -4959,6 +4970,10 @@ module TkComposite
@path = @epath = @frame.path
initialize_composite(*args)
end
+ unless defined? @delegates
+ @delegates = {}
+ @delegates['DEFAULT'] = @frame
+ end
end
def epath
@@ -4969,10 +4984,6 @@ module TkComposite
private :initialize_composite
def delegate(option, *wins)
- unless @delegates
- @delegates = {}
- @delegates['DEFAULT'] = @frame
- end
if @delegates[option].kind_of?(Array)
for i in wins
@delegates[option].push(i)
@@ -5077,7 +5088,13 @@ end
# widget_destroy_hook
require 'tkvirtevent'
TkBindTag::ALL.bind(TkVirtualEvent.new('Destroy'), proc{|widget|
- if widget.respond_to? :__destroy_hook__
+ if widget.respond_to?(:path)
+ w = widget.path
+ else
+ w = widget.to_s
+ end
+ if widget.respond_to?(:__destroy_hook__) &&
+ TkCore::INTERP._invoke('winfo','exist',w) == '1'
begin
widget.__destroy_hook__
rescue Exception
diff --git a/ext/tk/lib/tkafter.rb b/ext/tk/lib/tkafter.rb
index b24d6c72d3..eddfc16f63 100644
--- a/ext/tk/lib/tkafter.rb
+++ b/ext/tk/lib/tkafter.rb
@@ -34,7 +34,7 @@ class TkTimer
begin
ex_obj.cb_call
rescue Exception
- Tk_CBTBL[obj_id] = nil
+ ex_obj.cancel
""
end
end
@@ -143,6 +143,7 @@ class TkTimer
set_procs(*args) if args != []
@running = false
+ @in_callback = false
end
attr :after_id
diff --git a/ext/tk/sample/safe-tk.rb b/ext/tk/sample/safe-tk.rb
index 0c45ec3dbd..7050b236eb 100644
--- a/ext/tk/sample/safe-tk.rb
+++ b/ext/tk/sample/safe-tk.rb
@@ -44,10 +44,10 @@ cmd = Proc.new{|txt|
}
# call on the default master interpreter
-trusted_slave.eval_proc(cmd, 'trusted')
-safe_slave1.eval_proc(cmd, 'safe1')
-safe_slave2.eval_proc(cmd, 'safe2')
-cmd.call('master')
+trusted_slave.eval_proc(cmd, 'trusted') # label -> .w00012
+safe_slave1.eval_proc(cmd, 'safe1') # label -> .w00015
+safe_slave2.eval_proc(cmd, 'safe2') # label -> .w00018
+cmd.call('master') # label -> .w00021
TkTimer.new(2000, -1, proc{p ['safe1', safe_slave1.deleted?]}).start
TkTimer.new(2000, -1, proc{p ['safe2', safe_slave2.deleted?]}).start
@@ -57,6 +57,7 @@ TkTimer.new(10000, 1,
proc{
trusted_slave.eval_proc{Tk.root.destroy}
trusted_slave.delete
+ print "*** The trusted_slave is deleted by the timer.\n"
}).start
Tk.mainloop