http://qs321.pair.com?node_id=581114

liverpole has asked for the wisdom of the Perl Monks concerning the following question:

Greetings fellow monks,

A few days ago someone in the chatterbox gave a link to this site, which is a kind of word-association puzzle.

After trying it out, and getting hooked (it's addicting!), I decided to write a little Windows Perl/Tk GUI to help me cheat search for potential words. 8~D

When I created a Scrolled "ROText" widget, I realized there was an apparent bug which I have seen recently in other Perl/TK applications:

my $t = $w->Scrolled('ROText', '-bg', '#ffdfff', '-scrollbars', 'o +soe');

The above line is supposed to create a Scrolled Read-only Text (ROText) widget, with a lilac background color (0xffdfff), and optional 'South' and 'East' scrollbars.   When the widget is first filled with text, though, even if the "East" (right-side) scrollbar appears, the slider bar does not appear.

After resizing the whole GUI, however, the ROText window is resized, causing the scrollbar slider to appear as it should have done.  Another way to make the slider "pop into view" is to click the left mouse inside the ROText window, and move the mouse outside of the window (still holding the button down).

I've done some searching, both inside and outside of Perlmonks, for anyone with a similar problem, but haven't found anything that seems to address the issue.

Has anyone else seen this bug?

I have found that I can get around the problem by doing a $t->see("1.0"), followed by a $t->update(), before trying to see the end of the text window.

Here is a stripped-down version of the entire program.  To demonstrate the problem, type a valid address into the Entry widget marked "HTTP Address", and then type <Return>, or click the button marked "Load".  To demonstrate the workaround, select the Checkbutton marked "Workaround" first; leave it unselected to see the bug (in Windows):

#!/usr/bin/perl # # Example of an apparent Windows Perl/Tk bug in ROText & Text. # 061028 -- liverpole # # Strict use strict; use warnings; # Libraries use HTML::TreeBuilder; use LWP::Simple; use Tk; use Tk::Canvas; use Tk::ROText; # Globals my $workaround = 0; my $http_url = ""; # ============================================================= # Main Program -- create the GUI # ============================================================= # my $mw = new MainWindow(-title=>'Bug in Win32 Perl/Tk??'); my $f1 = $mw->Frame->pack(-expand => 0, -fill => 'x'); my $f2 = $mw->Frame->pack(-expand => 1, -fill => 'both'); my $b0 = $f1->Button( -bg => "green", -text => "Exit (Escape)", -command => sub { $mw->destroy } )->pack(-side => 'right'); my $pout = rotext($f2); my $f3 = $f1->Frame->pack(-side => 'left', -fill => 'none'); my $c1 = $f3->Checkbutton(-text => "Workaround", -variable => \$work +around) ->pack(-side => 'left'); my $l1 = $f3->Label(-text => " HTTP Address") ->pack(-side => 'left', -expand => 0, -fill => 'y'); my $e1 = $f3->Entry(-width => 64, -textvar => \$http_url) ->pack(-side => 'left', -expand => 0, -fill => 'y'); my $b1 = $f1->Button( -bg => "green", -text => "Load (Return)", -command => sub { load_url($http_url, $pout) } )->pack(-side => "left"); $mw->bind("<Escape>" => sub { $b0->invoke() }); $mw->bind("<Return>" => sub { $b1->invoke() }); $e1->focus(); MainLoop; # ============================================================ # Subroutines # ============================================================ sub load_url { my ($url, $pout) = @_; $pout->(); ($url || 0) or return; ($url =~ m|^http://i|) or $url = "http://$url"; my $content = get($url); my $font = "arial 10"; if (!defined($content)) { $pout->("Unable to load address '$url'", "$font bold", "red"); return; } $pout->($content); } sub rotext { my ($w) = @_; my $t = $w->Scrolled('ROText', '-bg', '#ffdfff', '-scrollbars', 'o +soe'); $t->pack(qw(-side top -expand 1 -fill both)); my $tag = 0; my $psub = sub { my ($text, $font, $color) = @_; ($text || 0) or $t->delete("1.0", "end"); ($text || 0) and $t->insert("end", "$text\n", ++$tag); ($font || 0) and $t->tagConfigure($tag, -font => $font) +; ($color || 0) and $t->tagConfigure($tag, -background => $color +); if ($workaround) { $t->see("1.0"); $t->toplevel->update(); } $t->see("end"); $t->toplevel->update(); }; return $psub; }

Can anyone tell me whether this is a known bug?  And, is there a better workaround than the one I've implemented above?  The bug also happens with a regular Scrolled "Text" window, but I'd be very interested if anyone knows what other conditions make it happen.

For the record, I am using ActiveState Perl, version 5.8.7, binary build 815 [211909], built on November 2, 2005.

Update:  Added <readmore> tags.


s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

Replies are listed 'Best First'.
Re: Bug in Win32 Perl/Tk Scrolled ROText widget with optional scrollbars
by GrandFather (Saint) on Oct 29, 2006 at 00:17 UTC

    I've seen the same issue with the Text widget and worked around it to a large degree by forcing the scroll bar to appear (omit the 'o' in the scroll bar specification). I'm using pretty much the same version of Perl.


    DWIM is Perl's answer to Gödel
Re: Bug in Win32 Perl/Tk Scrolled ROText widget with optional scrollbars
by liverpole (Monsignor) on Oct 29, 2006 at 01:55 UTC
    Thanks, Grandfather,

    However, part of the point of using optional scrollbars is that, of course, I only want the scrollbars to appear when they're necessary.

    So thanks for confirming that using non-optional scrollbars (changing "osoe" to "se" in my example) would make to the bug go away.

    But I am still interested in the larger problem of:

    • Is this a known (eg. reported) bug?  Why do optional scrollbars cause this bug to occur?
    • Is there some known workaround for this that I should be using?
    • Does that happen with other Scrolled widgets than "ROText" and "Text"?
    • Is there a better workaround than that of seeking elsewhere in the ROText widget, updating, and then seeking to the end?

    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: Bug in Win32 Perl/Tk Scrolled ROText widget with optional scrollbars
by zentara (Archbishop) on Oct 29, 2006 at 12:21 UTC
    Well I'm running on linux, and your script appears to run fine. I enter google.com (to get alot of text) and the scrollbars appear.

    When the widget is first filled with text, though, even if the "East" (right-side) scrollbar appears, the slider bar does not appear. After resizing the whole GUI, however, the ROText window is resized, causing the scrollbar slider to appear as it should have done. Another way to make the slider "pop into view" is to click the left mouse inside the ROText window, and move the mouse outside of the window (still holding the button down).

    I can't say for sure if it's your problem, but in many other Text widget scripts ( as you know ), it's often neccessary to do a $text->update to bring text into view.

    But this seems to be in the scrolled container that holds the text widget. So maybe you could try

    # do a 1 event loop iteration # process any Tk events like mouse moves/button presses/etc 1 while $MW->DoOneEvent( ALL_EVENTS | DONT_WAIT ); # or even a simple $mw->update; #or get the scrollbar and update it $scrollbar->update

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: Bug in Win32 Perl/Tk Scrolled ROText widget with optional scrollbars
by vkon (Curate) on Oct 29, 2006 at 12:06 UTC
    this is well known and fixed in Tk version 8.5.

    (I'm not sure about latest Tk 8.4.14)

    update: I was wrong, please '--' me.
    I replied too fast without deep investigation

    Sorrey!

      I am still seeing this bug ten years later on Active State and Strawberry builds for Win32. Does anyone have a workaround?