Scrolledwindow: scrolling automatically to the bottom


#1

hi,
i have a textview inside a scrolledwindow; the textview is not editable,
and only the scripts adds text to it.

when new text is added, i want to scroll to the bottom, so that the new
text is always visible.

as you can see, i tried:
scroll.vadjustment.value = scroll.vadjustment.upper -
scroll.vadjustment.page_size

this doesn’t work: the window scrolls, but the more recent part is
always below the window.

i believe that the value of scroll.vadjustment is not updated
immediately…

how can i solve this?

thanks

@edialog = Gtk::Window.new
@edialog.signal_connect("delete-event") do
  @edialog.hide
  true
end
vbox = Gtk::VBox.new
@edialog.add(vbox)
@ebuffer = Gtk::TextBuffer.new
@ebuffer.create_tag("query", "family" => "monospace", "weight" =>

Pango::FontDescription::WEIGHT_BOLD)
@ebuffer.create_tag(“result”, “family” => “monospace”, “wrap_mode”
=> Gtk::TextTag::WRAP_WORD)
@ebuffer.create_tag(“backtrace”, “family” => “monospace”, “weight”
=> Pango::FontDescription::WEIGHT_BOLD, “foreground” => “blue”)

textview = Gtk::TextView.new(@ebuffer)
textview.set_editable false
textview.cursor_visible = false
scroll = Gtk::ScrolledWindow.new
scroll.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
scroll.add(textview)
vbox.pack_start(scroll)
@eentry = Gtk::Entry.new
@ehistory = []
@ecurrent = 0
@eentry.signal_connect("key_press_event") do |widget, event|
  if event.state.control_mask? and event.keyval ==

Gdk::Keyval::GDK_p
@ecurrent = (@ecurrent + @ehistory.length - 1) %
@ehistory.length
@eentry.text = @ehistory[@ecurrent]
true
elsif event.state.control_mask? and event.keyval ==
Gdk::Keyval::GDK_n
@ecurrent = (@ecurrent + @ehistory.length + 1) %
@ehistory.length
@eentry.text = @ehistory[@ecurrent]
true
end
end
vbox.pack_start(@eentry, false, true, 0)
here = binding
@eentry.signal_connect(“activate”) do
begin
result = eval(@eentry.text, here)
@ebuffer.insert(@ebuffer.end_iter, “#{@eentry.text}\n”, “query”)
@ebuffer.insert(@ebuffer.end_iter, “#{result.inspect}\n”,
“result”)
rescue Exception => e
@ebuffer.insert(@ebuffer.end_iter, “#{e.message}\n”,
“backtrace”)
e.backtrace.each do |line|
@ebuffer.insert(@ebuffer.end_iter, “#{line}\n”, “backtrace”)
end
end
@ehistory << @eentry.text
@eacurrent = -1
@eentry.text = “”
scroll.vadjustment.value = scroll.vadjustment.upper -
scroll.vadjustment.page_size
end

@edialog.set_default_size(512, 384)

#2

i find the solution!

textview.signal_connect(“size-allocate”) do |widget, step, arg2|
@scroll.vadjustment.value = @scroll.vadjustment.upper -
@scroll.vadjustment.page_size
end


#3

Note that you could also use something like (not tested, but it captures
the essense of the idea):

textview.scroll_to_iter(textview.buffer.end_iter, 0.5, true, 0.0, 0.0)

http://ruby-gnome2.sourceforge.jp/hiki.cgi?Gtk%3A%3ATextView#scroll_to_iter

Note per the documentation, you may want to instead get the mark for the
end_iter, and use scroll_to_mark instead.

-pete

On Sun, Jul 29, 2007 at 07:50:30PM +0200, Pietro G. wrote:


This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/


ruby-gnome2-devel-en mailing list
removed_email_address@domain.invalid
https://lists.sourceforge.net/lists/listinfo/ruby-gnome2-devel-en


This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/


#4

On 18 April 2010 07:18, Marijn Van vliet
removed_email_address@domain.invalid wrote:

see the logic in it, but GTK is seriously lacking that a hack like this
is necessary. Thank you so much for sharing.

If I remember correctly (and I might not), the page_size is only
set correctly after the page is rendered (makes sense). So if
you draw into the window you have to wait until the GTK
events are cleared before scrolling to the bottom.

I have an app with a split pane and scrolled windows in each
pane and wanted to move the adjustment on the panes so
that the maximum of each pane was displayed. It took me
ages to figure out why the page size was always wrong.

      MikeC

#5

I solved the issues like this…

@buffer.signal_connect(“changed”) {
eob_mark =
@output.buffer.create_mark(nil,@output.buffer.start_iter.forward_to_end,false)
@output.scroll_mark_onscreen(eob_mark)
}

When I see a change to the window I set a mark at the end of the file
and then scroll to put the mark onscreen. This updates a across my
application that monitors 15-20 console connections and makes sure when
I bring the scrolled window to the front I am looking at the latest
output.


#6

Pietro G. wrote:

i find the solution!

textview.signal_connect(“size-allocate”) do |widget, step, arg2|
@scroll.vadjustment.value = @scroll.vadjustment.upper -
@scroll.vadjustment.page_size
end

We’ve been looking for ages to find the answer to this problem. We can
see the logic in it, but GTK is seriously lacking that a hack like this
is necessary. Thank you so much for sharing.