summaryrefslogtreecommitdiff
path: root/ext/tk
diff options
context:
space:
mode:
authornagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-07-31 07:59:18 +0000
committernagai <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-07-31 07:59:18 +0000
commit7126624b4effe49919e35224054cc48e86716f39 (patch)
tree081a374af97921e6315428db1bf7d58cbda40955 /ext/tk
parent89769459ba6ab5987ac257f35e2559726437e35b (diff)
* wrap the command-proc of TkScale : pass the numeric object to the proc
* better support for widgets created on Tk interpreter (without Ruby) * a little more stable on Multiple Tk interpreters running git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4242 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/tk')
-rw-r--r--ext/tk/lib/multi-tk.rb43
-rw-r--r--ext/tk/lib/tk.rb87
-rw-r--r--ext/tk/lib/tkafter.rb9
-rw-r--r--ext/tk/sample/safe-tk.rb2
4 files changed, 117 insertions, 24 deletions
diff --git a/ext/tk/lib/multi-tk.rb b/ext/tk/lib/multi-tk.rb
index 438c3c0816..99c25f2595 100644
--- a/ext/tk/lib/multi-tk.rb
+++ b/ext/tk/lib/multi-tk.rb
@@ -6,6 +6,13 @@ require 'tcltklib'
require 'thread'
################################################
+# ignore exception on the mainloop
+
+# TclTkLib.mainloop_abort_on_exception = false
+TclTkLib.mainloop_abort_on_exception = nil
+
+
+################################################
# exceptiopn to treat the return value from IP
class MultiTkIp_OK < Exception
def self.send(thred, ret=nil)
@@ -22,17 +29,11 @@ class MultiTkIp_OK < Exception
end
MultiTkIp_OK.freeze
+
################################################
# methods for construction
class MultiTkIp
-
- # ignore exception on the mainloop
- #TclTkLib.mainloop_abort_on_exception = false
- TclTkLib.mainloop_abort_on_exception = nil
-
- ######################################
-
- SLAVE_IP_ID = ['slave'.freeze, '00000']
+ SLAVE_IP_ID = ['slave'.freeze, '0']
@@IP_TABLE = {}
@@ -827,6 +828,32 @@ end
# depend on TclTkIp
class MultiTkIp
+ def mainloop(check_root = true, restart_on_dead = true)
+ unless restart_on_dead
+ @interp.mainloop(check_root)
+ else
+ begin
+ loop do
+ @interp.mainloop(check_root)
+ if check_root
+ begin
+ break if @interp._invoke('winfo', 'exists?', '.') == "1"
+ rescue Exception
+ break
+ end
+ end
+ end
+ rescue StandardError
+ if TclTkLib.mainloop_abort_on_exception != nil
+ STDERR.print("warning: Tk mainloop on ", @interp.inspect,
+ " receives ", $!.class.inspect,
+ " exception (ignore) : ", $!.message, "\n");
+ end
+ retry
+ end
+ end
+ end
+
def make_safe
@interp.make_safe
end
diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb
index 7b7b116a14..b25c5f3a1c 100644
--- a/ext/tk/lib/tk.rb
+++ b/ext/tk/lib/tk.rb
@@ -50,28 +50,27 @@ module TkComm
if ruby_class = WidgetClassNames[tk_class]
ruby_class_name = ruby_class.name
- gen_class_name = ruby_class_name + 'GeneratedOnTk'
+ # gen_class_name = ruby_class_name + 'GeneratedOnTk'
+ gen_class_name = ruby_class_name
classname_def = ''
elsif Object.const_defined?('Tk' + tk_class)
ruby_class_name = 'Tk' + tk_class
- gen_class_name = ruby_class_name + 'GeneratedOnTk'
+ # gen_class_name = ruby_class_name + 'GeneratedOnTk'
+ gen_class_name = ruby_class_name
classname_def = ''
else
ruby_class_name = 'TkWindow'
- gen_class_name = ruby_class_name + tk_class + 'GeneratedOnTk'
+ # gen_class_name = ruby_class_name + tk_class + 'GeneratedOnTk'
+ gen_class_name = 'TkWidget_' + tk_class
classname_def = "WidgetClassName = '#{tk_class}'.freeze"
end
unless Object.const_defined? gen_class_name
Object.class_eval "class #{gen_class_name}<#{ruby_class_name}
#{classname_def}
- def initialize(path)
- @path=path
- #Tk_WINDOWS[@path] = self
- TkCore::INTERP.tk_windows[@path] = self
- end
end"
end
- Object.class_eval "#{gen_class_name}.new('#{path}')"
+ Object.class_eval "#{gen_class_name}.new('widgetname'=>'#{path}',
+ 'without_creating'=>true)"
end
private :_genobj_for_tkwidget
module_function :_genobj_for_tkwidget
@@ -889,11 +888,34 @@ module TkCore
tk_call('info', *args)
end
- def mainloop(check_root = true)
- TclTkLib.mainloop(check_root)
+ def mainloop(check_root = true, restart_on_dead = true)
+ unless restart_on_dead
+ TclTkLib.mainloop(check_root)
+ else
+ begin
+ loop do
+ TclTkLib.mainloop(check_root)
+ if check_root
+ begin
+ break if TkWinfo.exist?('.')
+ rescue Exception
+ break
+ end
+ end
+ end
+ rescue StandardError
+ if TclTkLib.mainloop_abort_on_exception != nil
+ STDERR.print("warning: Tk mainloop on ", TkCore::INTERP.inspect,
+ " receives ", $!.class.inspect,
+ " exception (ignore) : ", $!.message, "\n");
+ end
+ retry
+ end
+ end
end
def mainloop_watchdog(check_root = true)
+ # watchdog restarts mainloop when mainloop is dead
TclTkLib.mainloop_watchdog(check_root)
end
@@ -3739,12 +3761,12 @@ class TkWindow<TkObject
def destroy
super
_destroy_children
- tk_call 'destroy', epath
if defined?(@cmdtbl)
for id in @cmdtbl
uninstall_cmd id
end
end
+ tk_call 'destroy', epath
uninstall_win
end
@@ -4392,12 +4414,46 @@ class TkScale<TkWindow
def create_self(keys)
if keys and keys != None
+ if keys.key?('command')
+ cmd = keys.delete('command')
+ keys['command'] = proc{|val| cmd.call(val.to_f)}
+ end
tk_call 'scale', @path, *hash_kv(keys)
else
tk_call 'scale', @path
end
end
+ def _wrap_command_arg(cmd)
+ proc{|val|
+ if val.kind_of?(String)
+ cmd.call(number(val))
+ else
+ cmd.call(val)
+ end
+ }
+ end
+ private :_wrap_command_arg
+
+ def configure_cmd(slot, value)
+ configure(slot=>value)
+ end
+
+ def configure(slot, value=None)
+ if (slot == 'command' || slot == :command)
+ configure('command'=>value)
+ elsif slot.kind_of?(Hash) &&
+ (slot.key?('command') || slot.key?(:command))
+ slot = _symbolkey2str(slot)
+ slot['command'] = __wrap_command_arg(slot.delete('command'))
+ end
+ super(slot, value)
+ end
+
+ def command(cmd=Proc.new)
+ configure('command'=>cmd)
+ end
+
def get(x=None, y=None)
number(tk_send('get', x, y))
end
@@ -5098,10 +5154,11 @@ TkBindTag::ALL.bind(TkVirtualEvent.new('Destroy'), proc{|widget|
else
w = widget.to_s
end
- if widget.respond_to?(:__destroy_hook__) &&
- TkCore::INTERP._invoke('winfo','exist',w) == '1'
+ if widget.respond_to?(:__destroy_hook__)
begin
- widget.__destroy_hook__
+ if TkCore::INTERP._invoke('winfo','exist',w) == '1'
+ widget.__destroy_hook__
+ end
rescue Exception
end
end
diff --git a/ext/tk/lib/tkafter.rb b/ext/tk/lib/tkafter.rb
index eddfc16f63..529b1e6cfb 100644
--- a/ext/tk/lib/tkafter.rb
+++ b/ext/tk/lib/tkafter.rb
@@ -114,7 +114,14 @@ class TkTimer
@id = Tk_CBID.join
Tk_CBID[1].succ!
- @cb_cmd = TkCore::INTERP.get_cb_entry(self.method(:do_callback))
+ # @cb_cmd = TkCore::INTERP.get_cb_entry(self.method(:do_callback))
+ @cb_cmd = TkCore::INTERP.get_cb_entry(proc{
+ begin
+ self.do_callback
+ rescue
+ self.cancel
+ end
+ })
@set_next = true
diff --git a/ext/tk/sample/safe-tk.rb b/ext/tk/sample/safe-tk.rb
index 90eb456653..6b6de8f848 100644
--- a/ext/tk/sample/safe-tk.rb
+++ b/ext/tk/sample/safe-tk.rb
@@ -55,6 +55,8 @@ safe_slave1.eval_proc(cmd, 'safe1') # label -> .w00016
safe_slave2.eval_proc(cmd, 'safe2') # label -> .w00020
cmd.call('master') # label -> .w00024
+#second_master = MultiTkIp.new(&cmd)
+
TkTimer.new(2000, -1, proc{p ['safe1', safe_slave1.deleted?]}).start
TkTimer.new(2000, -1, proc{p ['safe2', safe_slave2.deleted?]}).start
TkTimer.new(2000, -1, proc{p ['trusted', trusted_slave.deleted?]}).start