I have a custom container which provides scrolling functionality by embedding a Gtk::Grid
inside a Gtk::Viewport
. The scrolling part works perfectly except for one glitch. Whenever an on_size_allocate event occurs it causes the property_value
of the Gtk::Adjustment
to reset to 0 causing the scroll position to jump to the top. Since this could happen when any of the children emits a queue resize or even when the top level window loses focus the scroll position sort of never stays where it should. By overriding the container's on_size_allocate
handler I confirmed that the property_value
of Gtk::Adjustment
resets when I call the base class's on_size_allocate
. Below is my on_size_allocate
handler.
001 void CScrollGrid::on_size_allocate(Gtk::Allocation &oAlloc)
002 {
003 {
004 double dValue = m_refAdjustment->get_value();
005
006 std::cout << "size allocate (before), value: " << dValue << "\n";
007
008 Gtk::Widget::on_size_allocate(oAlloc);
009
010 std::cout
011 << "size allocate (after), value: "
012 << m_refAdjustment->get_value()
013 << "\n";
014
015 // Update scroll
016 {
017 int nMinimum;
018 int nDummy;
019
020 if (Gtk::ORIENTATION_VERTICAL
021 == m_eOrientation)
022 {
023 m_oGrid.get_preferred_height(nMinimum,
024 nDummy);
025 } else
026 {
027 m_oGrid.get_preferred_width(nMinimum,
028 nDummy);
029 }
030
031 m_refAdjustment->set_upper(nMinimum);
032 }
033
034 m_refAdjustment->property_value().set_value(dValue);
035
036 std::cout
037 << "size allocate (before fit), value: "
038 << m_refAdjustment->get_value()
039 << "\n";
040
041 Fit();
042 }
043 }
The stream output is as below.
size allocate (before), value: 146
size allocate (after), value: 0
size allocate (before fit), value: 0
At line 006 the stream output prints the correct 'value'. By line 010 the 'value' is reset to 0. As you can see that I have tried to apply the backed up value at line 034 but surprisingly the stream output at line 036 still returns 0! Looking at gtk_viewport_size_allocate
(gtk code) I couldn't see anything obvious that relates to resetting of the Gtk::Adjustment
.
Gtk::Adjustment::property_value
to stay stuck at 0 even after being set to a non-zero value?Gtk::Viewport
resets it's Gtk::Adjustment
s?Gtk::Adjustment::property_value
from being reset like what's happening here?NOTE: I didn't use Gtk::ScrolledWindow because of the following reason. The 'rows' inside the scrolled area could be of different heights. Irrespective of that the visible region needs to show the first and last row in full without clipping. When this is not possible, the last row is omitted and the extra space is converted as padding distributed evenly between top and bottom.
Figured out my mistake. Instead of calling the parent classes on_size_allocate
I should have just called set_allocation
. Also there is no need to update the Gtk::Adjustment
's upper limit, Gtk::ViewPort
does it internally. Following code works just fine.
001 void CScrollGrid::on_size_allocate(Gtk::Allocation &oAlloc)
002 {
003 set_allocation(oAlloc);
004
005 Fit();
006 }