http://www.perlmonks.org?node_id=963866

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

The code below illustrates a problem I'm having with Gtk2::TreeView (or here). It just shows a list of random words, and adds a new one at the bottom once every second. I'd like to automatically scroll the new word into view if the one just before it was visible. That way, this automatic scrolling won't annoy someone looking elsewhere in the tree view.

Everything words fine until something causes the tree view to shrink. Making the window smaller is an example. The actual application I'm working on has other examples, e.g., a Gtk2::Expander (or here). If you resize the window to be smaller, you should see the problem. The "gravity" of the scroll bar, I guess, moves it off the bottom after the shrink, turning off the automatic scrolling.

How can I keep my automatic scrolling, even after these kinds of events?

Thanks,

Jim

#!/usr/bin/perl use strict; use warnings; use Glib qw(TRUE FALSE); use Gtk2 -init; my($win,$tree)=createWin(); Glib::Timeout->add(1000,sub {tickCB($tree)}); $win->show_all(); Gtk2->main(); # # Creates the widgets in the application. Returns the main # window and tree view. # sub createWin { my($win,$scroll,$tree,$model); $win=new Gtk2::MainWindow(); $win->set_default_size(250,300); $win->signal_connect(destroy => \&Gtk2::main_quit); $win->add($scroll=new Gtk2::ScrolledWindow()); $scroll->add($tree=new Gtk2::TreeView()); $tree->set_rules_hint(TRUE); $tree->insert_column_with_attributes(-1,'Goo', new Gtk2::CellRendererText(),text => 0); $tree->set_model($model= new Gtk2::ListStore('Glib::String')); addWord($model) for 0 .. 100; showLast($tree); return ($win,$tree); } # # Called at regular intervals to add another random "word" # to the bottom of the tree view. If the previous word was # visible beforehand, scrolls the tree view so the new word # is visible. # sub tickCB { my($tree)=@_; my($model)=$tree->get_model(); my($numRows)=$model->iter_n_children(undef); my($lastVis)=($tree->get_visible_range())[1]; my($mustScroll)=$lastVis && $lastVis->get_indices() == $numRows-1; addWord($model); showLast($tree) if $mustScroll; return TRUE; } # # Adds a random "word" to the bottom of the tree view. # sub addWord { my($model)=@_; my(@cons)=grep !/[aeiou]/,'a' .. 'z'; $model->set($model->append(),0, $cons[rand @cons] . 'oo'); } # # Scrolls the tree view so the last row is visible. # sub showLast { my($tree)=@_; my($numRows)=$tree->get_model()->iter_n_children(undef); $tree->scroll_to_cell( new Gtk2::TreePath($numRows-1),undef,TRUE,0.0,1.0); }