Tk horizontal scrollbar infinite loop


#1

Hi,

I’m having a bizarre problem with Ruby/Tk. I’m running OS X 10.4 with
the standard ruby:

ruby 1.8.2 (2004-12-25) [powerpc-darwin8.0]

The code below is the simplest code that reproduces the problem.
Namely, when run, I see my window and scrollbar flicker rapidly,
apparently between two different sizes.


require ‘tk’

top = TkRoot.new
f = TkFrame.new(top)
sb = TkScrollbar.new(f,‘orient’=>‘horizontal’)
sb.pack(‘side’=>‘bottom’)
f.pack
Tk.mainloop

All of this is required. It works fine:

  • without the intermediate frame, f
  • without orient=>horizontal
  • without side=>bottom

Any help would be much appreciated. Please e-mail any replies to me at
removed_email_address@domain.invalid as I do not read this group regularly.

Thank you,
Chris


#2

From: “Chris” removed_email_address@domain.invalid
Subject: Tk horizontal scrollbar infinite loop
Date: Fri, 24 Feb 2006 14:38:32 +0900
Message-ID: removed_email_address@domain.invalid

The code below is the simplest code that reproduces the problem.
Namely, when run, I see my window and scrollbar flicker rapidly,
apparently between two different sizes.

Hmmm… It may be the trouble on your Tcl/Tk.
At least, I couldn’t reproduce your problem on my linux box.
Could you report me the result of the following Tcl/Tk script?


#3

Hmmm… It may be the trouble on your Tcl/Tk.
At least, I couldn’t reproduce your problem on my linux box.
Could you report me the result of the following Tcl/Tk script?

frame .f
scrollbar .f.sb -orient horizontal
pack .f.sb
pack .f

That works fine. The problem only shows up in Ruby/Tk.

c.


#4

I still have no idea what the problem is but I found a work around. The
following code runs fine:


require ‘tk’

root = TkRoot.new
f = TkFrame.new(root)
sb = TkScrollbar.new(f,‘orient’=>‘horizontal’)
sb.pack(‘side’=>‘bottom’,‘fill’=>‘x’,‘pady’=>‘1’)
f.pack(‘side’=>‘bottom’,‘fill’=>‘x’)

Tk.mainloop

That is, adding ‘pady’=>‘1’ fixes the problem. Note that ‘pady’=>‘0’
results in problem behavior.

I have also tried it on 1.8.4 and it appears there as well.
ruby 1.8.4 (2005-12-24) [powerpc-darwin8.5.0]

Assistance in tracking down the bug is still appreciated.

c.


#5

From: Chris A. removed_email_address@domain.invalid
Subject: Re: Tk horizontal scrollbar infinite loop
Date: Sat, 25 Feb 2006 01:06:27 +0900
Message-ID: removed_email_address@domain.invalid

I have also tried it on 1.8.4 and it appears there as well.
ruby 1.8.4 (2005-12-24) [powerpc-darwin8.5.0]

Do you mean that 1.8.4 has no problem? Or still has the problem?

I’m very sorry that I’m poor at English.

If 1.8.4 doesn’t have the problem, the bug may depend on
the following change.

Wed Nov 2 19:03:06 2005 Hidetoshi NAGAI removed_email_address@domain.invalid

    * ext/tcltklib/tcltklib.c (ip_rbUpdateObjCmd,
      ip_rb_threadUpdateObjCmd): passed improper flags to
      DoOneEvent().

Anyway, if :pady=>1 fixes the problem, the bug may depend on
‘update’ step.
Could you try the followings?
-----<test 1>------------------------------------------
require ‘tk’

f = TkFrame.new
sb = TkScrollbar.new(f, :orient=>:horizontal)
sb.pack(:side=>:bottom, :fill=>:x)
Tk.update_idletasks # <— add this
f.pack(:side=>:bottom, :fill=>:x)

Tk.mainloop

-----<test 2>------------------------------------------
require ‘tk’

evloop = Thread.new{Tk.mainloop}

f = TkFrame.new
sb = TkScrollbar.new(f, :orient=>:horizontal)
sb.pack(:side=>:bottom, :fill=>:x)
f.pack(:side=>:bottom, :fill=>:x)

evloop.join


#6

From: Chris A. removed_email_address@domain.invalid
Subject: Re: Tk horizontal scrollbar infinite loop
Date: Sun, 26 Feb 2006 00:48:22 +0900
Message-ID: removed_email_address@domain.invalid

1.8.4 still has the problem.
Both of the tests below have the problem.

Hmmm… That is a bad news.
Well, what message do you get from the following on 1.8.4?

require ‘tk’

r = Tk.root
f = TkFrame.new
sb = TkScrollbar.new(f, :orient=>:horizontal)

p [‘a’,
[[r.winfo_reqwidth,r.winfo_reqheight],
[r.winfo_width,r.winfo_height]],
[[f.winfo_reqwidth,f.winfo_reqheight],
[f.winfo_width,f.winfo_height]],
[[sb.winfo_reqwidth,sb.winfo_reqheight],
[sb.winfo_width,sb.winfo_height]]
]

sb.pack(:side=>:bottom, :fill=>:x)

p [‘b’,
[[r.winfo_reqwidth,r.winfo_reqheight],
[r.winfo_width,r.winfo_height]],
[[f.winfo_reqwidth,f.winfo_reqheight],
[f.winfo_width,f.winfo_height]],
[[sb.winfo_reqwidth,sb.winfo_reqheight],
[sb.winfo_width,sb.winfo_height]]
]

Tk.update

p [‘c’,
[[r.winfo_reqwidth,r.winfo_reqheight],
[r.winfo_width,r.winfo_height]],
[[f.winfo_reqwidth,f.winfo_reqheight],
[f.winfo_width,f.winfo_height]],
[[sb.winfo_reqwidth,sb.winfo_reqheight],
[sb.winfo_width,sb.winfo_height]]
]

f.pack(:side=>:bottom, :fill=>:x)

p [‘d’,
[[r.winfo_reqwidth,r.winfo_reqheight],
[r.winfo_width,r.winfo_height]],
[[f.winfo_reqwidth,f.winfo_reqheight],
[f.winfo_width,f.winfo_height]],
[[sb.winfo_reqwidth,sb.winfo_reqheight],
[sb.winfo_width,sb.winfo_height]]
]

Tk.update

p [‘e’,
[[r.winfo_reqwidth,r.winfo_reqheight],
[r.winfo_width,r.winfo_height]],
[[f.winfo_reqwidth,f.winfo_reqheight],
[f.winfo_width,f.winfo_height]],
[[sb.winfo_reqwidth,sb.winfo_reqheight],
[sb.winfo_width,sb.winfo_height]]
]

Tk.after(1000){
p [‘f’,
[[r.winfo_reqwidth,r.winfo_reqheight],
[r.winfo_width,r.winfo_height]],
[[f.winfo_reqwidth,f.winfo_reqheight],
[f.winfo_width,f.winfo_height]],
[[sb.winfo_reqwidth,sb.winfo_reqheight],
[sb.winfo_width,sb.winfo_height]]
]
}

Tk.mainloop

My Linux box returns

[“a”, [[200, 200], [1, 1]], [[1, 1], [1, 1]], [[2, 21], [1, 1]]]
[“b”, [[200, 200], [1, 1]], [[1, 1], [1, 1]], [[2, 21], [1, 1]]]
[“c”, [[200, 200], [200, 200]], [[2, 21], [1, 1]], [[2, 21], [1, 1]]]
[“d”, [[200, 200], [200, 200]], [[2, 21], [1, 1]], [[2, 21], [1, 1]]]
[“e”, [[42, 21], [42, 21]], [[42, 21], [42, 21]], [[42, 21], [42, 21]]]
[“f”, [[42, 21], [42, 21]], [[42, 21], [42, 21]], [[42, 21], [42, 21]]]

When sb.pack(:side=>:bottom, :fill=>:x, :pady=>1), returns

[“a”, [[200, 200], [1, 1]], [[1, 1], [1, 1]], [[2, 21], [1, 1]]]
[“b”, [[200, 200], [1, 1]], [[1, 1], [1, 1]], [[2, 21], [1, 1]]]
[“c”, [[200, 200], [200, 200]], [[2, 23], [1, 1]], [[2, 21], [1, 1]]]
[“d”, [[200, 200], [200, 200]], [[2, 23], [1, 1]], [[2, 21], [1, 1]]]
[“e”, [[42, 23], [42, 23]], [[42, 23], [42, 23]], [[42, 21], [42, 21]]]
[“f”, [[42, 23], [42, 23]], [[42, 23], [42, 23]], [[42, 21], [42, 21]]]


#7

Do you mean that 1.8.4 has no problem? Or still has the problem?

1.8.4 still has the problem.

Both of the tests below have the problem.

Thanks,
c.


#8

Hmmm… That is a bad news.
Well, what message do you get from the following on 1.8.4?

I get

[“a”, [[200, 200], [1, 1]], [[1, 1], [1, 1]], [[4, 16], [1, 1]]]
[“b”, [[200, 200], [1, 1]], [[1, 1], [1, 1]], [[4, 16], [1, 1]]]
[“c”, [[200, 200], [200, 200]], [[4, 16], [1, 1]], [[4, 16], [1, 1]]]
[“d”, [[200, 200], [200, 200]], [[4, 16], [1, 1]], [[4, 16], [1, 1]]]

and then the problem starts and e and d never appear.

With :pady=>1 I get

[“a”, [[200, 200], [1, 1]], [[1, 1], [1, 1]], [[4, 16], [1, 1]]]
[“b”, [[200, 200], [1, 1]], [[1, 1], [1, 1]], [[4, 16], [1, 1]]]
[“c”, [[200, 200], [200, 200]], [[4, 18], [1, 1]], [[4, 16], [1, 1]]]
[“d”, [[200, 200], [200, 200]], [[4, 18], [1, 1]], [[4, 16], [1, 1]]]
[“e”, [[34, 18], [34, 18]], [[34, 18], [34, 18]], [[34, 16], [34, 16]]]
[“f”, [[34, 18], [34, 18]], [[34, 18], [34, 18]], [[34, 16], [34, 16]]]

My Ruby is using the TclTk Framework, that is, OS X’s native scrollbar
widget, which explains the different dimensions.

As far as I can tell, the problem only occurs when the scrollbar is on
the
bottom or top of the window. It occurs even if there are other widgets
packed into the window as long as the scrollbar is at the top or bottom.

I have no problems with vertical scrollbars.

I ran

require ‘tk’

f = TkFrame.new
sb = TkScrollbar.new(f, :orient=>:horizontal)
sb.pack(:side=>:bottom, :fill=>:x)
f.pack(:side=>:bottom, :fill=>:x)

Tk.mainloop

with ‘-r profile’ for a while. The results are below.

Thanks for all your effort!

c.

^C % cumulative self self total
time seconds seconds calls ms/call ms/call name
99.42 97.59 97.59 1 97590.00 97590.00 TclTkLib.mainloop
0.22 97.81 0.22 1 220.00 220.00
TclTkIp#initialize
0.21 98.02 0.21 12 17.50 54.17 Kernel.require
0.02 98.04 0.02 13 1.54 1.54 Module#included
0.01 98.05 0.01 14 0.71 0.71
Module#module_function
0.01 98.06 0.01 43 0.23 0.93 Array#each
0.01 98.07 0.01 17 0.59 0.59 Module#autoload
0.01 98.08 0.01 4 2.50 2.50 String#to_i
0.01 98.09 0.01 1 10.00 10.00
TkFrame#initialize
0.01 98.10 0.01 5 2.00 2.00
TkCore._tk_call_core
0.01 98.11 0.01 60 0.17 0.17 Kernel.freeze
0.01 98.12 0.01 102 0.10 0.10 Kernel.autoload
0.01 98.13 0.01 499 0.02 0.02
Module#method_added
0.01 98.14 0.01 1 10.00 10.00
TkComm.install_cmd
0.00 98.14 0.00 2 0.00 0.00
TkWindow#initialize
0.00 98.14 0.00 2 0.00 0.00 Method#arity
0.00 98.14 0.00 5 0.00 0.00
TkCore::Tk_OBJECT_TABLE#method_missing
0.00 98.14 0.00 3 0.00 0.00 TclTkIp#_invoke
0.00 98.14 0.00 1 0.00 10.00
Tk::Encoding.encoding_system
0.00 98.14 0.00 2 0.00 5.00 TkWindow#pack
0.00 98.14 0.00 1 0.00 0.00
TkScrollbar#create_self
0.00 98.14 0.00 1 0.00 0.00 String#length
0.00 98.14 0.00 1 0.00 0.00 Fixnum#>
0.00 98.14 0.00 5 0.00 0.00 TkUtil._conv_args
0.00 98.14 0.00 2 0.00 0.00 Hash#==
0.00 98.14 0.00 10 0.00 0.00 Kernel.extend
0.00 98.14 0.00 114 0.00 0.00 Hash#[]=
0.00 98.14 0.00 1 0.00 0.00
TkUtil::CallbackSubst#_setup_subst_table
0.00 98.14 0.00 9 0.00 0.00 String#+
0.00 98.14 0.00 3 0.00 0.00 TclTkIp#_toUTF8
0.00 98.14 0.00 1 0.00 0.00 Proc#new
0.00 98.14 0.00 6 0.00 0.00 Hash#delete
0.00 98.14 0.00 1 0.00 0.00
TkBindTag#initialize
0.00 98.14 0.00 1 0.00 0.00 Array#join
0.00 98.14 0.00 1 0.00 0.00 Proc#==
0.00 98.14 0.00 1 0.00 0.00 Hash#clear
0.00 98.14 0.00 3 0.00 0.00
Kernel.instance_eval
0.00 98.14 0.00 11 0.00 0.00 Array#push
0.00 98.14 0.00 1 0.00 0.00 TkObject#path
0.00 98.14 0.00 1 0.00 0.00
TkCore::Tk_OBJECT_TABLE#initialize
0.00 98.14 0.00 220 0.00 0.00
Kernel.singleton_method_added
0.00 98.14 0.00 12 0.00 0.00
TclTkIp#_invoke_without_enc
0.00 98.14 0.00 1 0.00 0.00
#TclTkIp:0x586148.get_cb_entry
0.00 98.14 0.00 2 0.00 0.00
TkConfigMethod.__conv_keyonly_opts
0.00 98.14 0.00 5 0.00 0.00 Kernel.send
0.00 98.14 0.00 2 0.00 0.00 TkPack.configure
0.00 98.14 0.00 5 0.00 0.00 Symbol#to_s
0.00 98.14 0.00 10 0.00 0.00
TclTkIp#_return_value
0.00 98.14 0.00 1 0.00 0.00
TkComm._curr_cmd_id
0.00 98.14 0.00 1 0.00 0.00 Hash#update
0.00 98.14 0.00 38 0.00 0.00 Module#const_set
0.00 98.14 0.00 1 0.00 0.00
TkWindow#create_self
0.00 98.14 0.00 2 0.00 0.00 String#split
0.00 98.14 0.00 2 0.00 0.00
#TclTkIp:0x586148.tk_windows
0.00 98.14 0.00 2 0.00 0.00
TkConfigMethod.__ruby2val_optkeys
0.00 98.14 0.00 2 0.00 0.00
#TclTkIp:0x586148.add_tk_procs
0.00 98.14 0.00 1 0.00 0.00
#TclTkIp:0x586148.__getip
0.00 98.14 0.00 5 0.00 0.00 TclTkIp#ip_id
0.00 98.14 0.00 2 0.00 0.00 TkObject#epath
0.00 98.14 0.00 4 0.00 0.00 String#succ!
0.00 98.14 0.00 4 0.00 0.00
TkCore.tk_call_without_enc
0.00 98.14 0.00 6 0.00 0.00 Kernel.method
0.00 98.14 0.00 6 0.00 0.00 Hash#[]
0.00 98.14 0.00 1 0.00 0.00 TclTkIp#_fromUTF8
0.00 98.14 0.00 9 0.00 0.00 Hash#key?
0.00 98.14 0.00 1 0.00 0.00 Proc#call
0.00 98.14 0.00 1 0.00 0.00
#TclTkIp:0x586148.tk_cmd_tbl
0.00 98.14 0.00 1 0.00 0.00
#TclTkIp:0x586148.init_ip_env
0.00 98.14 0.00 43 0.00 0.00 Module#private
0.00 98.14 0.00 2 0.00 0.00 Kernel.tainted?
0.00 98.14 0.00 1 0.00 0.00 Hash#has_key?
0.00 98.14 0.00 1 0.00 0.00 Array#size
0.00 98.14 0.00 2 0.00 0.00 TkUtil.hash_kv
0.00 98.14 0.00 1 0.00 0.00 Class#initialize
0.00 98.14 0.00 44 0.00 0.00 Fixnum#|
0.00 98.14 0.00 4 0.00 0.00 String#<<
0.00 98.14 0.00 5 0.00 0.00
TkCore._ip_invoke_core
0.00 98.14 0.00 6 0.00 0.00
Module#const_defined?
0.00 98.14 0.00 9 0.00 0.00 Hash#each
0.00 98.14 0.00 13 0.00 1.54 Module#include
0.00 98.14 0.00 6 0.00 0.00 TkComm._epath
0.00 98.14 0.00 6 0.00 0.00 Kernel.===
0.00 98.14 0.00 1 0.00 0.00
Module#attr_accessor
0.00 98.14 0.00 16 0.00 0.00 Array#[]
0.00 98.14 0.00 24 0.00 0.00 Class#inherited
0.00 98.14 0.00 13 0.00 0.00
Module#append_features
0.00 98.14 0.00 1 0.00 0.00 TclTkIp#__invoke
0.00 98.14 0.00 10 0.00 22.00 Class#new
0.00 98.14 0.00 10 0.00 0.00 Module#extended
0.00 98.14 0.00 4 0.00 0.00
Kernel.respond_to?
0.00 98.14 0.00 1 0.00 0.00 Enumerable.find
0.00 98.14 0.00 1 0.00 0.00
#<Class(TkCallbackEntry):2c2046>#initialize
0.00 98.14 0.00 2 0.00 0.00
TkTreatFont.__font_optkeys
0.00 98.14 0.00 1 0.00 0.00 TkComm._toUTF8
0.00 98.14 0.00 5 0.00 0.00
#TclTkIp:0x586148.tk_object_table
0.00 98.14 0.00 2 0.00 0.00
TkConfigMethod.__methodcall_optkeys
0.00 98.14 0.00 5 0.00 0.00 Hash#default
0.00 98.14 0.00 2 0.00 0.00
TkConfigMethod.__keyonly_optkeys
0.00 98.14 0.00 1 0.00 0.00 Kernel.==
0.00 98.14 0.00 3 0.00 3.33 TkKernel#new
0.00 98.14 0.00 4 0.00 0.00 Array#<<
0.00 98.14 0.00 1 0.00 0.00
Tk::Encoding.encoding=
0.00 98.14 0.00 13 0.00 0.00 Kernel.taint
0.00 98.14 0.00 1 0.00 0.00
TkComm._next_cmd_id
0.00 98.14 0.00 1 0.00 0.00 Module#freeze
0.00 98.14 0.00 2 0.00 0.00 Array#==
0.00 98.14 0.00 1 0.00 0.00
Exception#initialize
0.00 98.14 0.00 5 0.00 0.00 Kernel.class
0.00 98.14 0.00 1 0.00 10.00 TkCore.tk_call
0.00 98.14 0.00 3 0.00 0.00 Object#initialize
0.00 98.14 0.00 3 0.00 0.00 String#==
0.00 98.14 0.00 1 0.00 97590.00 TkCore.mainloop
0.00 98.14 0.00 4 0.00 0.00 Hash#empty?
0.00 98.14 0.00 1 0.00 0.00
c00000#<cb_entry:2bd6b8>.[]=
0.00 98.14 0.00 2 0.00 0.00
Module#private_class_method
0.00 98.14 0.00 1 0.00 0.00 Module#<
0.00 98.14 0.00 6 0.00 0.00 Kernel.proc
0.00 98.14 0.00 1 0.00 0.00
Exception#set_backtrace
0.00 98.14 0.00 1 0.00 0.00
Module#attr_reader
0.00 98.14 0.00 1 0.00 0.00
TkBindTag#new_by_name
0.00 98.14 0.00 2 0.00 0.00
TkUtil._symbolkey2str
0.00 98.14 0.00 5 0.00 0.00 String#to_s
0.00 98.14 0.00 1 0.00 0.00
#TclTkIp:0x586148.create_table
0.00 98.14 0.00 2 0.00 0.00 Array#pop
0.00 98.14 0.00 17 0.00 0.00 Fixnum#<<
0.00 98.14 0.00 1 0.00 0.00
TkUtil::CallbackSubst#_define_attribute_aliases
0.00 98.14 0.00 1 0.00 0.00
Exception#backtrace
0.00 98.14 0.00 16 0.00 0.00 Kernel.kind_of?
0.00 98.14 0.00 10 0.00 0.00
Module#extend_object
0.00 98.14 0.00 12 0.00 0.00 Fixnum#==
0.00 98.14 0.00 3 0.00 0.00 Regexp#===
0.00 98.14 0.00 2 0.00 0.00
TkComm.install_win
0.00 98.14 0.00 3 0.00 0.00 Hash#initialize
0.00 98.14 0.00 1 0.00 0.00 Array#collect
0.00 98.16 0.00 1 0.00 98160.00 #toplevel



#9

From: Chris A. removed_email_address@domain.invalid
Subject: Re: Tk horizontal scrollbar infinite loop
Date: Sun, 26 Feb 2006 06:23:49 +0900
Message-ID: removed_email_address@domain.invalid

I can generate the problem in wish as well. The previous test on wish did
not use the -fill or -side arguments to pack, when I add them the same
problem occurs.

I conclude that this is a Tcl/Tk Framework bug, not a Ruby/Tk bug.

That is an unfortunate situation for you.
However, That is a good news for Ruby/Tk. :wink:


#10

I can generate the problem in wish as well. The previous test on wish
did
not use the -fill or -side arguments to pack, when I add them the same
problem occurs.

I conclude that this is a Tcl/Tk Framework bug, not a Ruby/Tk bug.


frame .f
scrollbar .f.sb -orient horizontal
pack .f.sb -side bottom -fill x
pack .f -side bottom -fill x

Thanks for your time,
c.


#11

On Sun, 26 Feb 2006 13:47:03 +0900, you wrote:

I conclude that this is a Tcl/Tk Framework bug, not a Ruby/Tk bug.

That is an unfortunate situation for you.
However, That is a good news for Ruby/Tk. :wink:

i assume someone sent off the bug report to activestate? i imagine
they’d want to get that fixed :slight_smile:
http://home.cogeco.ca/~tsummerfelt1
telnet://ventedspleen.dyndns.org