Optimizing GtkListBox for many rows

2015-08-31 Thread Timm Bäder
Hi,

if you've ever worked with a GtkListBox that has many rows, you probably
know about the performance problems.  These are mostly not even related
to drawing or scrolling.  The biggest problem is just allocating all of
those rows (bonus points if every row uses a composite template, so you
have to parse XML and create all those widgets/objects, set the
properties, etc.) and size allocation.

And I guess basically everyone knows how mobile UIs solve (or avoid)
thsi problem: they just estimate the list height, and only keep as many
rows around as they need to cover the current viewport.  This way
obviously needs a backing model implementation (which we have now with
GListModel) and a function that just takes an item and assigns the data
to the corresponsing widgets etc.

Earlier this year I've started to play around with such a
widget-recycling listbox implementation here:
https://github.com/baedert/listbox-test (don't judge my commit
messages).  It's currrently written in Vala (so I can write stuff
faster).  The repo includes a few demos which work more or less, you
just have to (un)comment the corresponding lines int the Makefile.  The
ideal case, i.e. "all rows are visible and all rows have the same
height" seems to work already.

I've talked to at least 4 people about this and I know a few others have
worked on an implementation, too, so I think it's better to just
collect all the knowledge we have instead of smoeone writing it on
their own.  The current implementation faces a few problems, mainly
regarding scrolling:

  - Of course, the scrollbar jumps around.  If seen people say that
nowadays, scrollbars should be seen as a rough indicator so maybe
this is a non-issue but in extreme cases it seems pretty awkward
to me.
  - Scrolling by dragging the scrollbar is completely broken if you have
uneven row heights.  Android solves (read avoids) this by scrolling
row-by-row in those cases. I think Alex said something about this at
the GTK+ BoF at Guadec.
  - We estimate the list size by just looking at the height of the
current widgets.  This means that the estimated height changes
almost every time we remove/add a new row (given that rows have
uneven height).  I explicitly decided agains saving the height of
every row we ever allocated and using that as a better estimate,
because it makes the estimation much more complex (think about the
row height depending on the data in the model...) and I don't want
people to notoriously scroll through all the listboxes once to fix
the scrolling.
  - We currently just pool the used widgets, i.e. we never free any of
them.  I'm not sure how other existing implementations solve this or
if it's just not a problem at all.
  - IIRC Benjamin told me once that just faking widgets to A11y isn't
really possible ATM.
  - I'm not sure if there's gtk+-internal API for this, but we'd
basically need to tell the css machinery that a widget is at
position i, without i being the actual current position in the
widget hierarchy (so :nth-child works as expected).
  - Of course, this is currently completely independent from GtkListBox
so we'd need to integrate it there.


For reference, the Android implementation can be found at [1] and
features nice methods like findViewByPredicateInHeadersOrFooters, but
also lots of informative comments. I'm not sure how many of those 4KLOC
Java we really need (and how many that would be in C...), but Android's
ListView does much more than the current GtkListBox, like headers that
stick to the top of the list when scrolled. On the other hand, I'm
certain that e.g. Christian wants exactly that so if such a feature
would completely change the entire implementation, we should maybe care
about it from the very start.


The current performance is OK I think.  The repo includes a tweet-row.ui
that I just copied from corebird and removed a few things, but it's
still around 330 lines of XML and that works as far as I can see.


I hope I didn't forget anything and I'm curious what you alll think and
what solutions you have for all those problems, cheers.


[1] 
https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/ListView.java
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: g_error_free() warning on null pointer

2015-08-31 Thread Michael McConville
Simon McVittie wrote:
> On 16/08/15 20:23, Michael McConville wrote:
> > Emmanuele Bassi wrote:
> >> You expected the *_free() functions in GLib to be NULL-safe. They
> >> aren't, except for g_free().
> > 
> > g_error_free is. Maybe others too, I haven't checked. It just prints
> > annoying console warnings.
> 
> The intention throughout the GLib-based stack is that if a
> g_return[_val]_if_fail() is hit, it indicates that the caller has
> called the function incorrectly, in a way that is considered to be
> undefined behaviour
> . Undefined
> behaviour does not mean "your code will crash"; it means "any result
> is valid, and it is up to the compiler or library author what
> happens". It does in practice end up meaning "your code is wrong",
> because the majority of the possible implementations of undefined
> behaviour are not what you wanted.

I still don't understand how this is relevant. I already understand what
undefined behavior is and how it relates to compilers/optimization.
However, this sort of smoke and mirrors inexactness doesn't apply to
GLib - there's a single implementation and we can just go and look at
the source code and see what it does. In the case of g_error_free, this
is:

 1) print an annoying warning
 2) call g_free(), which is NULL-safe
 3) call g_slice_free(), which is NULL-safe
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: g_error_free() warning on null pointer

2015-08-31 Thread Sébastien Wilmet
On Mon, Aug 31, 2015 at 11:03:40PM -0400, Michael McConville wrote:
>  1) print an annoying warning

Not always, as Simon explained already, the g_return_if_fail()/...
functions can be disabled, in which case the program continues its
execution and will usually crash.

See the --enable-debug configure option of GLib:
https://developer.gnome.org/glib/unstable/glib-building.html

In the docs, if it is not mentioned whether NULL is accepted or not, it
means that it is not supported. Except when the documentation needs to
be fixed, of course, which can happen from time to time.

--
Sébastien
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list