Strange behaviour of elm_genlist_item_show function
Open, Showstopper IssuesPublic


When creating genlist and use elm_genlist_item_show function immediately it has strange behaviour. When item can be shown with desired Elm_Genlist_Item_Scrollto_Type parameter it works, but if it cannot fit easily it doesn't make anything. Same functionality works fine with ecore_job, or idler. I've prepared test code with 30 elements(from console you can specify item to scroll and type of scroll). When trying to show item 18 and below with scroll top it doesn't work, but with scroll bottom it does.

From my investigation it looks like problem with calculation in _calc_job function in elm_genlist.c. See gdb output below(in this situation it calculates that there is no need to scroll):


if ((pan_w > (sd->show_item->x + sd->show_item->item->block->x))
                && (pan_h > (sd->show_item->y + sd->show_item->item->block->y
                             + dy)))


#gdb genlist_test
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
Find the GDB manual and other documentation resources online at:
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from genlist_test...(no debugging symbols found)...done.
(gdb) b elm_genlist.c:885
No symbol table is loaded. Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (elm_genlist.c:885) pending.
(gdb) r 20 2
Starting program: /home/mariusz.g/test/genlist_test 20 2
warning: the debug information found in "/lib64/" does not match "/lib64/" (CRC mismatch).

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/".
Traceback (most recent call last):

File "/usr/share/gdb/auto-load/usr/lib/", line 7, in <module>
  import eo_gdb

ImportError: No module named 'eo_gdb'
[New Thread 0x7fffed163700 (LWP 21953)]
[New Thread 0x7fffe7be9700 (LWP 21954)]
[Thread 0x7fffe7be9700 (LWP 21954) exited]
[New Thread 0x7fffe73e8700 (LWP 21955)]
Focus item: 20, scroll to 2
[New Thread 0x7fffe5b92700 (LWP 21956)]
[New Thread 0x7fffe5391700 (LWP 21957)]

Thread 1 "genlist_test" hit Breakpoint 1, _calc_job (data=<optimized out>) at lib/elementary/elm_genlist.c:885
885 if ((pan_w > (sd->show_item->x + sd->show_item->item->block->x))
(gdb) bt
#0 _calc_job (data=<optimized out>) at lib/elementary/elm_genlist.c:885
#1 0x00007ffff79db8ba in _elm_genlist_pan_efl_canvas_group_group_calculate (obj=0x800000065e716a2e, psd=0x9e2360) at lib/elementary/elm_genlist.c:2499
#2 0x00007ffff746b715 in efl_canvas_group_calculate (obj=0x800000065e716a2e) at ../src/lib/evas/canvas/efl_canvas_group.eo.c:16
#3 0x00007ffff746c5bc in evas_call_smarts_calculate (eo_e=0x800000020e7169a4) at lib/evas/canvas/evas_object_smart.c:1011
#4 0x00007ffff74411e5 in evas_canvas_smart_objects_calculate (obj=0x800000020e7169a4) at ../src/lib/evas/canvas/evas_canvas.eo.c:208
#5 0x00007ffff7444ea5 in evas_smart_objects_calculate (obj=<optimized out>) at ../src/lib/evas/canvas/evas_canvas.eo.c:767
#6 0x00007ffff7ace82f in _elm_win_obj_intercept_show (data=<optimized out>, obj=0x80000001fe7169a2) at lib/elementary/efl_ui_win.c:2925
#7 0x00007ffff746494e in evas_object_intercept_call_show (obj=0x751500, eo_obj=0x80000001fe7169a2) at lib/evas/canvas/evas_object_intercept.c:71
#8 _evas_object_intercept_call_internal (eo_obj=eo_obj@entry=0x80000001fe7169a2, obj=0x751500, cb_type=cb_type@entry=EVAS_OBJECT_INTERCEPT_CB_VISIBLE, internal=internal@entry=0, args=args@entry=0x7fffffffd9f0)

at lib/evas/canvas/evas_object_intercept.c:105

#9 0x00007ffff7465214 in _evas_object_intercept_call (eo_obj=eo_obj@entry=0x80000001fe7169a2, cb_type=cb_type@entry=EVAS_OBJECT_INTERCEPT_CB_VISIBLE, internal=internal@entry=0)

at lib/evas/canvas/evas_object_intercept.c:225

#10 0x00007ffff7ad262f in _efl_ui_win_efl_gfx_visible_set (obj=0x80000001fe7169a2, sd=0x751830, vis=<optimized out>) at lib/elementary/efl_ui_win.c:2383
#11 0x00007ffff2551381 in efl_gfx_visible_set (obj=0x80000001fe7169a2, v=<optimized out>) at ../src/lib/efl/interfaces/efl_gfx.eo.c:21
#12 0x0000000000401264 in elm_main ()
#13 0x00000000004012b2 in main ()
(gdb) print pan_h
$1 = 690
(gdb) print sd->show_item->y
$2 = 460
(gdb) print sd->show_item->item->block->y
$3 = 0
(gdb) print dy
$4 = 298
(gdb) print sd->h
$5 = 298

mariusz.g added projects: Restricted Project, efl.Nov 15 2017, 3:46 AM
mariusz.g triaged this task as Showstopper Issues priority.Nov 16 2017, 12:10 AM
mariusz.g removed cedric as the assignee of this task.Nov 16 2017, 12:13 AM
mariusz.g added a subscriber: cedric.

looks it is releated with D5428.
it is under the review now.

D5428 is related to optimizations when list is not homogenous. Defect I reported is related to homogenous mode in which sizes and positions are known early. To show e.g. 9999 item elementary just calculates 1st item, and knows size of genlist and item's offset so only neighborhood is realized.
It is related with boundary conditions. For example if we have 10000 items, homogenous mode, and we are using elm_genlist_item_show it will work instantly with 100, 1000, and 9799'th item, but will fail with 9999'th item.

There is special case for last item, I think this is to avoid this issue, so assuming that there are X items visible items from 0 to (size-X) and last one are fine, and others fail.

if (sd->check_scroll)
     eo_do(sd->pan_obj, elm_obj_pan_content_size_get(&pan_w, &pan_h));
    if (EINA_INLIST_GET(sd->show_item) == sd->items->last)         <------------------
       sd->scroll_to_type = ELM_GENLIST_ITEM_SCROLLTO_IN;          <------------------

     switch (sd->scroll_to_type)
          dy = sd->h;

          dy = sd->h / 2;

          dy = 0;
     if ((sd->show_item) && (sd->show_item->item->block))
          if ((pan_w > (sd->show_item->x + sd->show_item->item->block->x))
              && (pan_h > (sd->show_item->y + sd->show_item->item->block->y
                           + dy)))
minkyu added a subscriber: minkyu.Nov 16 2017, 6:59 PM

It look weird if check_scroll is true even though homogeneous is set.
Although I didn't investigate deeply, I found something.

  1. It works fine if disabled the compress mode on your test code.
  1. It works fine if remove this routine at genlist.
diff --git a/src/lib/elementary/elm_genlist.c b/src/lib/elementary/elm_genlist.c
index 9c1be93..8a9add5 100644
--- a/src/lib/elementary/elm_genlist.c
+++ b/src/lib/elementary/elm_genlist.c
@@ -7057,7 +7057,6 @@ _elm_genlist_item_coordinates_calc(Elm_Gen_Item *it,
         if ((it->item->queued) || (!it->item->mincalcd) || (sd->queue))
           deferred_show = EINA_TRUE;
-   else if (it->item->block->w < 1) deferred_show = EINA_TRUE;
    if (deferred_show)

As Sanghyeon Jade Lee suggests this patch is fixing issue:

diff --git a/src/lib/elm_genlist.c b/src/lib/elm_genlist.c
index 6bd36b8..e903bde 100644
--- a/src/lib/elm_genlist.c
+++ b/src/lib/elm_genlist.c
@@ -946,7 +946,8 @@ _calc_job(void *data)
         if ((sd->show_item) && (sd->show_item->item->block))
-             if ((pan_w > (sd->show_item->x + sd->show_item->item->block->x))
+             if (!sd->queue || 
+               (pan_w > (sd->show_item->x + sd->show_item->item->block->x))
                  && (pan_h > (sd->show_item->y + sd->show_item->item->block->y
                               + dy)))