Compare commits

...

31 Commits

Author SHA1 Message Date
Mike Blumenkrantz 62c557848b wip 2019-10-28 14:07:17 -04:00
Mike Blumenkrantz 71b546efba Revert "elm/genlist: redo focus adapter management on item blocks"
This reverts commit 3b290bd22f.
2019-10-28 12:53:26 -04:00
Mike Blumenkrantz 24b032f7fa efl_ui: mark Efl.Ui.Focus.Autoscroll_Mode beta
this cannot currently be used for anything and was not explicitly stabilized

Differential Revision: https://phab.enlightenment.org/D10540
2019-10-28 08:58:26 -04:00
Mike Blumenkrantz 31c6f03d89 efl_ui: remove Efl.Ui.Slider_Indicator_Visible_Mode
this cannot be used for anything and serves no purpose

Differential Revision: https://phab.enlightenment.org/D10539
2019-10-28 08:58:26 -04:00
Mike Blumenkrantz f8ecd60e2e ci: remove existing base_dir ccache config on osx build before adding new one
ensure that this file does not balloon to infinite size

Differential Revision: https://phab.enlightenment.org/D10538
2019-10-28 08:58:26 -04:00
Mike Blumenkrantz bbe26283eb tests/loop_timer: add port of ecore_timer behavior tests for loop_timer
ensure that the behavior here is also working exactly as expected

Differential Revision: https://phab.enlightenment.org/D10531
2019-10-28 08:29:14 -04:00
Mike Blumenkrantz 8500747800 tests/ecore: make timer behavior test even more strict
we need to also verify that timers will process out of order solely based
on their timestamps and ignoring whether they are "recently-added"

additionally verify the behavior of timer interval changing and re-instantiating

ref T8434

Differential Revision: https://phab.enlightenment.org/D10530
2019-10-28 08:29:14 -04:00
Mike Blumenkrantz d9e51f7900 tests/genlist: add behavior testing for nearly all genlist events
this simulates a number of user interactions to ensure that various
functionalities of genlist actually work, including but not limited to:
* selection
* highlighting
* item focus
* scrolling
* filtering
* dragging
* item reordering

ref T8433

Differential Revision: https://phab.enlightenment.org/D10528
2019-10-28 08:29:14 -04:00
Mike Blumenkrantz f27196739b elm/genlist: set pan need recalc during item move on item position change
item move operations require pan recalc in order to process the item block
positioning updates

@fix

Differential Revision: https://phab.enlightenment.org/D10533
2019-10-28 08:29:14 -04:00
Mike Blumenkrantz 7026523b1d elm/genlist: fix "drag" smart callback
this is only a smart callback and not an eo callback

@fix

Differential Revision: https://phab.enlightenment.org/D10527
2019-10-28 08:29:14 -04:00
Mike Blumenkrantz d68fb42a11 elm/genlist: trigger filter,done callback immediately if no filter queue exists
the documentation says this should trigger when filtering is done, and if
no filtering is pending then it is done

@fix

Differential Revision: https://phab.enlightenment.org/D10526
2019-10-28 08:29:14 -04:00
Mike Blumenkrantz b28466862c elm/genlist: slightly simplify use of _item_filtered_get()
passing the smart data here (which we always have) makes the function
a little clearer to read. similarly, we can check whether the filter_data
pointer is set inside the function to avoid having to check it everywhere else

Differential Revision: https://phab.enlightenment.org/D10525
2019-10-28 08:29:14 -04:00
Mike Blumenkrantz 1f444443e8 elm/genlist: defer recalc when applying a name filter
this may be called successively during the same mainloop iteration,
so it's important to defer this as much as possible

Differential Revision: https://phab.enlightenment.org/D10524
2019-10-28 08:29:14 -04:00
Mike Blumenkrantz 4aa0598952 elm/genlist: remove calc jobs
now that we have a sane and consistent sizing calc mechanism, we no longer
need to be randomly creating jobs to do additional side calcs in addition
to our other multiple bespoke calculation methods

instead, we can now call the calc function directly during the group calc
to perform all the calcs at once and avoid the overhead of constantly triggering
calc jobs

a possible future improvement here could be to remove the _calc_job() call in
the internal pan object's group_calculate, as this is likely a duplicated op
but it will require additional testing to verify

unit test performance (e.g., tree) increases roughly 50-80% after this patch

Differential Revision: https://phab.enlightenment.org/D10523
2019-10-28 08:29:14 -04:00
Mike Blumenkrantz 97d8ca96d3 elm/genlist: don't process entire item queue on each item add
this is a colossal waste of time. it ends up realizing every single item
immediately even if it won't be visible, which defeats the purpose of all
the batching and viewport calculations that genlist explicitly does to
avoid exactly this type of behavior

Differential Revision: https://phab.enlightenment.org/D10522
2019-10-28 08:29:14 -04:00
Mike Blumenkrantz 6a634bfac4 elm/genlist: freeze/thaw canvas when processing item queue
Differential Revision: https://phab.enlightenment.org/D10521
2019-10-28 08:29:14 -04:00
Mike Blumenkrantz 3b290bd22f elm/genlist: redo focus adapter management on item blocks
creating these based on item block realize state is a good idea, but
genlist items can be realized even if their item block is not realized
and so this ends up failing in that case

Differential Revision: https://phab.enlightenment.org/D10520
2019-10-28 08:29:14 -04:00
Mike Blumenkrantz 703d08c2d4 elm/genlist: only add calc job on theme apply if already finalized
not a required operation otherwise

Differential Revision: https://phab.enlightenment.org/D10519
2019-10-28 08:29:13 -04:00
Mike Blumenkrantz 8874f65f62 elm/genlist: remove misleading "changed" signal
this was never implemented or documented anywhere and serves only to be
misleading for anyone reading the code

Differential Revision: https://phab.enlightenment.org/D10518
2019-10-28 08:29:13 -04:00
Mike Blumenkrantz 822cee155f elm/genlist: fix item highlight/unhighlight eventing on clicks
* highlight should only be triggered on mouse down, as that is the point of
  interaction with an item which indicates it is "in use"; a mouse-up event
  cannot occur on an item which has not previously received a mouse-down event,
  so toggling this on mouse-up will be wrong/duplicated 100% of the time
* unhighlight should only be triggered during mouse-up events if the list is
  in no-select mode, as it will otherwise be implicitly during selection if
  necessary

this should ensure that these events are emitted exactly one time and correctly
for each click event

Differential Revision: https://phab.enlightenment.org/D10517
2019-10-28 08:29:13 -04:00
Mike Blumenkrantz 5f744fcdfb tests/ecore: add more grueling timer throughput test
this verifies that:
* newly-created timers are not triggered in the next loop iteration
* newly-created timers can be triggered the second loop after created
* multiple timers can be triggered in a single loop iteration
* timers are effectively added to the pending timer list

ref T8434

Differential Revision: https://phab.enlightenment.org/D10516
2019-10-28 08:29:13 -04:00
Mike Blumenkrantz c95ea83f10 efl/timer: correctly handle recursion for timer processing
if the currently-processed timer is recursively deleted (efl_del) while
it is inside the timer tick event callback, we must correctly handle this
case:

* in the place where a timer's inlist is de-linked, we must check to see
  if the timer is the current timer and then update that pointer with the next
  timer in the list
* in the post-tick part of timer processing, we must NOT update the current timer
  pointer if we detect that it has been updated recursively

this fixes processing of timers in the mainloop to trigger more than one legacy timer
per mainloop iteration and likely has some (positive) impact on mainloop throughput

@fix

Differential Revision: https://phab.enlightenment.org/D10515
2019-10-28 08:29:13 -04:00
Mike Blumenkrantz 2c2329f41c efl/timer: don't attempt instantiating timers until they're finalized
this will fail anyway so don't bother

Differential Revision: https://phab.enlightenment.org/D10514
2019-10-28 08:29:13 -04:00
Mike Blumenkrantz 7d63b0b3b8 tests/genlist: fix tree test sizing
for some reason I used 10px as the base height of a genlist item when clearly
they are more like 30px

Differential Revision: https://phab.enlightenment.org/D10513
2019-10-28 08:29:13 -04:00
Mike Blumenkrantz a683b1fe10 tests/elm: add utility function to trigger a mouse drag
a drag may require a lot of internal calculating to successfully trigger
the intended test behavior, so this has a flag which allows it to perform
loop iterations and canvas calcs in order to be more universal, along with
a global #define for determining exactly how many mouse moves were triggered

Differential Revision: https://phab.enlightenment.org/D10512
2019-10-28 08:29:13 -04:00
Mike Blumenkrantz 164c7ac818 tests/elm: make argv a static char so it never goes out of scope and crashes
Differential Revision: https://phab.enlightenment.org/D10511
2019-10-28 08:29:13 -04:00
Mike Blumenkrantz 15011c11c0 tests/elm: add util functions for clicking objects/parts with event flags
this is useful for synthesizing e.g., double click events

Differential Revision: https://phab.enlightenment.org/D10510
2019-10-28 08:29:13 -04:00
Mike Blumenkrantz 9061d680bd tests/elm: add util callback for incrementing an int data
this is a common functionality

Differential Revision: https://phab.enlightenment.org/D10509
2019-10-28 08:29:13 -04:00
Mike Blumenkrantz 87bde91882 evas/font: simplify handling strings when constructing font names
no need to strcpy here when we can just pass the length to stringshare directly

CID 1382854

Differential Revision: https://phab.enlightenment.org/D10441
2019-10-28 08:29:13 -04:00
Mike Blumenkrantz bfea21dd63 edje: selectively inhibit content,changed events when changing swallowed parts
ref T8321

Differential Revision: https://phab.enlightenment.org/D10508
2019-10-28 08:10:56 -04:00
Mike Blumenkrantz 4349747b06 tests/eina: use #ifdef guard for block which can only occur inside ifdef
this value is set in the corresponding #ifdef block above, so use the same
guard here to make code more readable

CID 1400948

Differential Revision: https://phab.enlightenment.org/D10321
2019-10-28 08:10:56 -04:00
17 changed files with 562 additions and 130 deletions

View File

@ -7,6 +7,7 @@ if [ "$DISTRO" != "" ] ; then
docker exec $(cat $HOME/cid) ccache -pz
else
cp .ci/ccache.conf ~/.ccache
sed -iE '/^base_dir/d' ~/.ccache/ccache.conf
echo "base_dir = $pwd" >> ~/.ccache/ccache.conf
ccache -pz
fi

View File

@ -82,7 +82,8 @@ _check_timer_event_catcher_add(void *data, const Efl_Event *event)
if (array[i].desc == EFL_LOOP_TIMER_EVENT_TIMER_TICK)
{
if (timer->listening++ > 0) return;
_efl_loop_timer_util_instanciate(timer->loop_data, timer);
if (timer->finalized)
_efl_loop_timer_util_instanciate(timer->loop_data, timer);
// No need to walk more than once per array as you can not del
// a partial array
return;
@ -471,8 +472,12 @@ _efl_loop_timer_efl_object_parent_set(Eo *obj, Efl_Loop_Timer_Data *pd, Efl_Obje
// Remove the timer from all possible pending list
first = eina_inlist_first(EINA_INLIST_GET(pd));
if (first == pd->loop_data->timers)
pd->loop_data->timers = eina_inlist_remove
(pd->loop_data->timers, EINA_INLIST_GET(pd));
{
/* if this timer is currently being processed, update the pointer here so it is not lost */
if (pd == pd->loop_data->timer_current)
pd->loop_data->timer_current = (Efl_Loop_Timer_Data*)EINA_INLIST_GET(pd)->next;
pd->loop_data->timers = eina_inlist_remove(pd->loop_data->timers, EINA_INLIST_GET(pd));
}
else if (first == pd->loop_data->suspended)
pd->loop_data->suspended = eina_inlist_remove
(pd->loop_data->suspended, EINA_INLIST_GET(pd));
@ -641,14 +646,24 @@ _efl_loop_timer_expired_call(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, double when
efl_ref(timer->object);
eina_evlog("+timer", timer, 0.0, NULL);
/* this can remove timer from its inlist in the legacy codepath */
efl_event_callback_call(timer->object, EFL_LOOP_TIMER_EVENT_TIMER_TICK, NULL);
eina_evlog("-timer", timer, 0.0, NULL);
// may have changed in recursive main loops
// this current timer can not die yet as we hold a reference on it
/* this is tricky: the current timer cannot be deleted, but it CAN be removed from its inlist,
* thus breaking timer processing
*/
if (pd->timer_current)
pd->timer_current = (Efl_Loop_Timer_Data *)
EINA_INLIST_GET(pd->timer_current)->next;
{
if (pd->timer_current == timer)
pd->timer_current = (Efl_Loop_Timer_Data *)EINA_INLIST_GET(pd->timer_current)->next;
/* assume this has otherwise been modified either due to recursive mainloop processing or
* the timer being removed from its inlist and carefully updating pd->timer_current in the
* process as only the most elite of engineers would think to do
*/
}
_efl_loop_timer_reschedule(timer, when);
efl_unref(timer->object);
}

View File

@ -1803,6 +1803,7 @@ struct _Edje
Eina_Bool canvas_animator : 1;
Eina_Bool has_state_clip : 1;
Eina_Bool has_recalc_event_cb : 1;
Eina_Bool has_content_change_event_cb : 1;
};
struct _Edje_Calc_Params_Map

View File

@ -608,6 +608,10 @@ _efl_canvas_layout_efl_object_event_callback_priority_add(Eo *obj, Edje *pd, con
{
pd->has_recalc_event_cb = EINA_TRUE;
}
else if (desc == EFL_CONTENT_EVENT_CONTENT_CHANGED)
{
pd->has_content_change_event_cb = EINA_TRUE;
}
return efl_event_callback_priority_add(efl_super(obj, MY_CLASS), desc, priority, func, user_data);
}
@ -621,6 +625,10 @@ _efl_canvas_layout_efl_object_event_callback_array_priority_add(Eo *obj, Edje *p
{
pd->has_recalc_event_cb = EINA_TRUE;
}
else if (array[i].desc == EFL_CONTENT_EVENT_CONTENT_CHANGED)
{
pd->has_content_change_event_cb = EINA_TRUE;
}
}
return efl_event_callback_array_priority_add(efl_super(obj, MY_CLASS), array, priority, user_data);
}

View File

@ -3088,7 +3088,8 @@ _edje_efl_content_content_set(Edje *ed, const char *part, Efl_Gfx_Entity *obj_sw
eud->u.swallow.child = obj_swallow;
}
}
efl_event_callback_call(ed->obj, EFL_CONTENT_EVENT_CONTENT_CHANGED, obj_swallow);
if (ed->has_content_change_event_cb)
efl_event_callback_call(ed->obj, EFL_CONTENT_EVENT_CONTENT_CHANGED, obj_swallow);
return EINA_TRUE;
}

View File

@ -42,23 +42,9 @@ enum Efl.Ui.Focus.Move_Policy
Left, Right, Up, Down, Tab, or Shift+Tab.]]
}
enum @beta Efl.Ui.Slider_Indicator_Visible_Mode
{
[[Slider's indicator visibility mode.
@since 1.13
]]
on_drag, [[show indicator on mouse down or change in slider value]]
always, [[Always show the indicator.]]
on_focus, [[Show the indicator on focus]]
none [[Never show the indicator ]]
}
enum Efl.Ui.Focus.Autoscroll_Mode
enum @beta Efl.Ui.Focus.Autoscroll_Mode
{
[[Focus Autoscroll Mode
@since 1.10
]]
show, [[Directly show the focused region or item automatically.]]
none, [[Do not show the focused region or item automatically.]]

View File

@ -4875,16 +4875,6 @@ static const struct {
{ EFL_UI_SOFTCURSOR_MODE_OFF, "off" }
};
static const struct {
Efl_Ui_Slider_Indicator_Visible_Mode val;
const char *str;
} _enum_map_slider_indicator_visible_mode[] = {
{ EFL_UI_SLIDER_INDICATOR_VISIBLE_MODE_ON_DRAG, "on_drag" },
{ EFL_UI_SLIDER_INDICATOR_VISIBLE_MODE_ALWAYS, "always" },
{ EFL_UI_SLIDER_INDICATOR_VISIBLE_MODE_ON_FOCUS, "on_focus" },
{ EFL_UI_SLIDER_INDICATOR_VISIBLE_MODE_NONE, "none" },
};
static const struct {
Efl_Ui_Focus_Move_Policy val;
const char *str;
@ -4994,7 +4984,6 @@ _efl_config_global_efl_config_config_set(Eo *obj EINA_UNUSED, void *_pd EINA_UNU
CONFIG_SETD(scroll_thumbscroll_momentum_animation_duration_max_limit);
CONFIG_SETE(focus_autoscroll_mode);
CONFIG_SETE(slider_indicator_visible_mode);
CONFIG_SETD(longpress_timeout);
CONFIG_SETE(softcursor_mode);
CONFIG_SETD(tooltip_delay);
@ -5138,7 +5127,6 @@ _efl_config_global_efl_config_config_get(const Eo *obj EINA_UNUSED, void *_pd EI
CONFIG_GETD(scroll_thumbscroll_momentum_animation_duration_max_limit);
CONFIG_GETE(focus_autoscroll_mode);
CONFIG_GETE(slider_indicator_visible_mode);
CONFIG_GETD(longpress_timeout);
CONFIG_GETE(softcursor_mode);
CONFIG_GETD(tooltip_delay);

View File

@ -101,7 +101,6 @@
cmd(SIG_ITEM_UNFOCUSED, "item,unfocused", "") \
cmd(SIG_PRESSED, "pressed", "") \
cmd(SIG_RELEASED, "released", "") \
cmd(SIG_CHANGED, "changed", "") \
cmd(SIG_FILTER_DONE, "filter,done", "")
ELM_PRIV_GENLIST_SIGNALS(ELM_PRIV_STATIC_VARIABLE_DECLARE);
@ -167,7 +166,7 @@ static void _access_activate_cb(void *data EINA_UNUSED,
Elm_Object_Item *item);
static void _decorate_item_set(Elm_Gen_Item *);
static void _internal_elm_genlist_clear(Evas_Object *obj);
static Eina_Bool _item_filtered_get(Elm_Gen_Item *it);
static Eina_Bool _item_filtered_get(Elm_Gen_Item *it, Elm_Genlist_Data *sd);
static void _elm_genlist_tree_effect_stop(Elm_Genlist_Data *sd);
static Eina_Bool _elm_genlist_tree_effect_setup(Elm_Genlist_Data *sd);
@ -184,14 +183,6 @@ static const Elm_Action key_actions[] = {
{NULL, NULL}
};
static inline void
_add_calc_job(Elm_Genlist_Data *sd)
{
ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
if (!efl_alive_get(sd->obj)) return;
sd->calc_job = ecore_job_add(_calc_job, sd->obj);
}
static void
_size_cache_free(void *data)
{
@ -297,7 +288,6 @@ _elm_genlist_pan_efl_gfx_entity_position_set(Eo *obj, Elm_Genlist_Pan_Data *psd,
psd->wsd->pan_changed = EINA_TRUE;
evas_object_smart_changed(obj);
ELM_SAFE_FREE(psd->wsd->calc_job, ecore_job_del);
}
static void
@ -333,9 +323,7 @@ _elm_genlist_pan_efl_gfx_entity_size_set(Eo *obj, Elm_Genlist_Pan_Data *psd, Ein
// away or appeared to queue a job to deal with it. it should settle in
// the end to a steady-state
if (old.w != size.w)
_add_calc_job(sd);
else
ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
efl_canvas_group_change(sd->obj);
super:
efl_gfx_entity_size_set(efl_super(obj, MY_PAN_CLASS), size);
@ -481,7 +469,8 @@ _item_content_realize(Elm_Gen_Item *it,
if (elm_widget_is(content))
{
if (!calc)
elm_widget_tree_unfocusable_set(content, it->item->unfocusable);
if (!calc && (!it->item->unfocusable))
_elm_widget_full_eval(content);
}
}
@ -784,7 +773,7 @@ _must_recalc_idler(void *data)
{
ELM_GENLIST_DATA_GET(data, sd);
_add_calc_job(sd);
efl_canvas_group_change(sd->obj);
sd->must_recalc_idler = NULL;
return ECORE_CALLBACK_CANCEL;
}
@ -794,12 +783,13 @@ _calc_job(void *data)
{
int in = 0;
Item_Block *itb, *chb = NULL;
ELM_GENLIST_DATA_GET(data, sd);
Elm_Genlist_Data *sd = data;
Eina_Bool minw_change = EINA_FALSE;
Eina_Bool did_must_recalc = EINA_FALSE;
Evas_Coord minw = -1, minh = 0, y = 0, ow = 0, vw = 0;
Evas *e;
sd->need_calc = EINA_FALSE;
evas_object_geometry_get(sd->pan_obj, NULL, NULL, &ow, &sd->h);
if (sd->mode == ELM_LIST_COMPRESS)
elm_interface_scrollable_content_viewport_geometry_get
@ -906,7 +896,7 @@ _calc_job(void *data)
if (did_must_recalc)
{
if (!sd->must_recalc_idler)
sd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, data);
sd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, sd->obj);
}
if (!sd->show_item) sd->check_scroll = EINA_FALSE;
if (sd->check_scroll)
@ -918,7 +908,6 @@ _calc_job(void *data)
_item_scroll(sd);
}
sd->calc_job = NULL;
evas_object_smart_changed(sd->pan_obj);
evas_event_thaw(e);
evas_event_thaw_eval(e);
@ -957,11 +946,15 @@ _elm_genlist_efl_canvas_group_group_calculate(Eo *obj, Elm_Genlist_Data *sd)
{
itb->must_recalc = EINA_TRUE;
}
_add_calc_job(sd);
sd->need_calc = EINA_TRUE;
}
minw = vmw;
minh = vmh;
}
else
sd->need_calc = EINA_TRUE;
if (sd->need_calc)
_calc_job(sd);
if (sd->scr_minw)
{
@ -1052,22 +1045,26 @@ _item_tree_effect_before(Elm_Gen_Item *it)
return ECORE_CALLBACK_CANCEL;
}
static void
/* returns true if change occurred */
static Eina_Bool
_item_position(Elm_Gen_Item *it,
Evas_Object *view,
Evas_Coord it_x,
Evas_Coord it_y)
{
if (!it) return;
if (!view) return;
Eina_Position2D pos;
if (!it) return EINA_FALSE;
if (!view) return EINA_FALSE;
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
Evas *e = evas_object_evas_get(sd->obj);
evas_event_freeze(e);
pos = efl_gfx_entity_position_get(view);
efl_gfx_entity_geometry_set(view, EINA_RECT(it_x, it_y, it->item->w, it->item->h));
evas_object_show(view);
evas_event_thaw(e);
evas_event_thaw_eval(e);
return (pos.x != it_x) || (pos.y != it_y);
}
static void
@ -1704,7 +1701,11 @@ _item_cache_find(Elm_Gen_Item *it)
efl_wref_del(itc->base_view, &itc->base_view);
itc->base_view = NULL;
EINA_LIST_FREE(itc->contents, obj)
elm_widget_tree_unfocusable_set(obj, EINA_FALSE);
{
if (elm_widget_is(obj))
elm_widget_tree_unfocusable_set(obj, it->item->unfocusable);
evas_object_show(obj);
}
itc->contents = NULL;
_item_cache_free(itc);
return EINA_TRUE;
@ -1722,7 +1723,8 @@ _content_cache_add(Elm_Gen_Item *it, Eina_List **cache)
{
*cache = eina_list_append(*cache, content);
eina_hash_del_by_key(pd->content_item_map, &content);
elm_widget_tree_unfocusable_set(content, EINA_TRUE);
if (elm_widget_is(content)) elm_widget_tree_unfocusable_set(content, EINA_TRUE);
evas_object_hide(content);
}
return *cache;
@ -2429,8 +2431,8 @@ _item_block_position(Item_Block *itb, const int blk_idx)
sd = it->item->wsd;
if (sd->reorder_it == it) continue;
if (!it->filtered && sd->filter_data && it->itc->func.filter_get)
_item_filtered_get(it);
if (it->itc->func.filter_get)
_item_filtered_get(it, sd);
if (it->hide)
{
if (it->realized) evas_object_hide(VIEW(it));
@ -2622,9 +2624,7 @@ _elm_genlist_pan_efl_canvas_group_group_calculate(Eo *obj, Elm_Genlist_Pan_Data
if (sd->pan_changed)
{
ecore_job_del(sd->calc_job);
sd->calc_job = NULL;
_calc_job(sd->obj);
_calc_job(sd);
sd->pan_changed = EINA_FALSE;
}
@ -3577,8 +3577,8 @@ _elm_genlist_efl_ui_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd)
itb->changed = EINA_TRUE;
}
if (sd->obj)
_add_calc_job(sd);
if (sd->obj && efl_finalized_get(obj))
efl_canvas_group_change(sd->obj);
elm_layout_sizing_eval(obj);
evas_event_thaw(e);
evas_event_thaw_eval(e);
@ -3700,7 +3700,7 @@ _item_block_del(Elm_Gen_Item *it)
itb->items = eina_list_remove(itb->items, it);
itb->count--;
itb->changed = EINA_TRUE;
_add_calc_job(sd);
efl_canvas_group_change(sd->obj);
if (itb->count < 1)
{
Item_Block *itbn;
@ -3768,8 +3768,6 @@ _item_block_del(Elm_Gen_Item *it)
{
sd->pan_changed = EINA_TRUE;
evas_object_smart_changed(sd->pan_obj);
ecore_job_del(sd->calc_job);
sd->calc_job = NULL;
}
}
@ -3848,7 +3846,7 @@ _elm_genlist_item_del_serious(Elm_Gen_Item *it)
sd->group_items = eina_list_remove(sd->group_items, it);
ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
_add_calc_job(sd);
efl_canvas_group_change(sd->obj);
ELM_SAFE_FREE(it->item, free);
}
@ -4016,8 +4014,7 @@ _item_mouse_move_cb(void *data,
sd->movements++;
}
ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
efl_event_callback_legacy_call
(WIDGET(it), EFL_UI_EVENT_DRAG, eo_it);
evas_object_smart_callback_call(WIDGET(it), "drag", eo_it);
return;
}
if ((!it->down) || (sd->longpressed))
@ -4025,6 +4022,7 @@ _item_mouse_move_cb(void *data,
ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
if ((sd->reorder_mode) && (sd->reorder_it))
{
Eina_Bool changed;
evas_object_geometry_get(sd->pan_obj, &ox, &oy, &ow, &oh);
if (ev->cur.canvas.y < (oy + (sd->reorder_it->item->h / 2)))
@ -4046,11 +4044,13 @@ _item_mouse_move_cb(void *data,
y_pos = it_scrl_y;
if (it->deco_all_view)
_item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
changed = _item_position(it, it->deco_all_view, it->item->scrl_x, y_pos);
else
_item_position(it, VIEW(it), it->item->scrl_x, y_pos);
changed = _item_position(it, VIEW(it), it->item->scrl_x, y_pos);
_add_calc_job(sd);
efl_canvas_group_change(sd->obj);
if (changed)
efl_canvas_group_change(sd->pan_obj);
}
return;
}
@ -4654,7 +4654,7 @@ newblock:
itb->count++;
itb->changed = EINA_TRUE;
it->item->block = itb;
_add_calc_job(itb->sd);
efl_canvas_group_change(itb->sd->obj);
if (itb->count > itb->sd->max_items_per_block)
{
@ -4813,7 +4813,6 @@ _item_process_post(Elm_Genlist_Data *sd, Elm_Gen_Item *it)
if (sd->pan_changed)
{
evas_object_smart_changed(sd->pan_obj);
ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
}
}
if (show_me) it->item->block->show_me = EINA_TRUE;
@ -4850,9 +4849,10 @@ _queue_process(Elm_Genlist_Data *sd)
{
int n;
double t0, t;
Evas *e = evas_object_evas_get(sd->obj);
t0 = ecore_time_get();
evas_event_freeze(e);
for (n = 0; (sd->queue) && (n < ITEM_QUEUE_MAX); n++)
{
Elm_Gen_Item *it;
@ -4869,6 +4869,8 @@ _queue_process(Elm_Genlist_Data *sd)
if ((t - t0) > (ecore_animator_frametime_get())) break;
}
}
evas_event_thaw(e);
evas_event_thaw_eval(e);
return n;
}
@ -4896,7 +4898,7 @@ _item_idle_enterer(void *data)
if (wakeup)
{
// wake up mainloop
_add_calc_job(sd);
efl_canvas_group_change(sd->obj);
}
if (ok == ECORE_CALLBACK_CANCEL) sd->queue_idle_enterer = NULL;
@ -4926,6 +4928,7 @@ _item_queue(Elm_Genlist_Data *sd,
// FIXME: why does a freeze then thaw here cause some genlist
// elm_genlist_item_append() to be much much slower?
// evas_event_freeze(evas_object_evas_get(sd->obj));
/*
while ((sd->queue) && ((!sd->blocks) || (!sd->blocks->next)))
{
ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
@ -4937,7 +4940,7 @@ _item_queue(Elm_Genlist_Data *sd,
ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
_queue_process(sd);
}
*/
// evas_event_thaw(evas_object_evas_get(sd->obj));
// evas_event_thaw_eval(evas_object_evas_get(sd->obj));
evas_object_geometry_get(sd->obj, NULL, NULL, &w, NULL);
@ -5141,7 +5144,7 @@ _item_mouse_up_cb(void *data,
}
else
{
_add_calc_job(sd);
efl_canvas_group_change(sd->obj);
}
edje_object_signal_emit(VIEW(it), SIGNAL_REORDER_DISABLED, "elm");
if (_elm_config->atspi_mode)
@ -5168,7 +5171,10 @@ _item_mouse_up_cb(void *data,
}
}
if (!it->selected && it->highlighted)
/* this is handled implicitly in _item_unselect() below unless there
* will be no select
*/
if (!it->selected && it->highlighted && _is_no_select(it))
_item_unhighlight(it);
if ((ev->flags != EVAS_BUTTON_NONE) ||
@ -5191,7 +5197,9 @@ _item_mouse_up_cb(void *data,
{
if (!it->selected)
{
/* this should only be handled on mouse down
_item_highlight(it);
*/
if (_item_select(it)) goto deleted;
}
else
@ -5220,7 +5228,9 @@ _item_mouse_up_cb(void *data,
_item_unselect(it2);
}
}
/* this should only be handled on mouse down
_item_highlight(it);
*/
if (_item_select(it)) goto deleted;
}
@ -5384,6 +5394,15 @@ _item_unrealize(Elm_Gen_Item *it)
it->want_unrealize = EINA_FALSE;
}
static void
_item_temp_realize(Elm_Gen_Item *it, const int index)
{
it->item->unfocusable = EINA_TRUE;
_item_realize(it, index, EINA_TRUE);
_elm_genlist_item_unrealize(it, EINA_TRUE);
it->item->unfocusable = EINA_FALSE;
}
static Eina_Bool
_item_block_recalc(Item_Block *itb, const int blk_idx, Eina_Bool qadd)
{
@ -5400,8 +5419,7 @@ _item_block_recalc(Item_Block *itb, const int blk_idx, Eina_Bool qadd)
{
show_me |= it->item->show_me;
if (!it->filtered) _item_filtered_get(it);
if (it->hide)
if (!_item_filtered_get(it, itb->sd))
{
if (it->realized) evas_object_hide(VIEW(it));
continue;
@ -5418,8 +5436,7 @@ _item_block_recalc(Item_Block *itb, const int blk_idx, Eina_Bool qadd)
{
if (!size || (it->item->expanded_depth != size->expanded_depth))
{
_item_realize(it, blk_idx + vis_count, EINA_TRUE);
_elm_genlist_item_unrealize(it, EINA_TRUE);
_item_temp_realize(it, blk_idx + vis_count);
}
else
{
@ -5440,10 +5457,7 @@ _item_block_recalc(Item_Block *itb, const int blk_idx, Eina_Bool qadd)
it->item->mincalcd = EINA_TRUE;
}
else
{
_item_realize(it, blk_idx + vis_count, EINA_TRUE);
_elm_genlist_item_unrealize(it, EINA_TRUE);
}
_item_temp_realize(it, blk_idx + vis_count);
}
}
else
@ -5531,7 +5545,7 @@ _update_job(void *data)
}
if (position)
{
_add_calc_job(sd);
efl_canvas_group_change(sd->obj);
}
evas_event_thaw(e);
evas_event_thaw_eval(e);
@ -5885,7 +5899,6 @@ _elm_genlist_efl_canvas_group_group_del(Eo *obj, Elm_Genlist_Data *sd)
EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
_evas_viewport_resize_cb, sd);
ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
ELM_SAFE_FREE(sd->update_job, ecore_job_del);
ELM_SAFE_FREE(sd->pan_obj, evas_object_del);
ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
@ -6038,7 +6051,6 @@ _internal_elm_genlist_clear(Evas_Object *obj)
sd->pan_changed = EINA_TRUE;
if (!sd->queue)
{
ELM_SAFE_FREE(sd->calc_job, ecore_job_del);
sd->anchor_item = NULL;
ELM_SAFE_FREE(sd->queue_idle_enterer, ecore_idle_enterer_del);
ELM_SAFE_FREE(sd->must_recalc_idler, ecore_idler_del);
@ -6978,7 +6990,7 @@ _elm_genlist_first_item_get(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
{
Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
while (it && sd->filter && !_item_filtered_get(it))
while (it && sd->filter && !_item_filtered_get(it, sd))
it = ELM_GEN_ITEM_NEXT(it);
return EO_OBJ(it);
@ -6992,7 +7004,7 @@ _elm_genlist_last_item_get(const Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
if (!sd->items) return NULL;
it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
while (it && sd->filter && !_item_filtered_get(it))
while (it && sd->filter && !_item_filtered_get(it, sd))
it = ELM_GEN_ITEM_PREV(it);
return EO_OBJ(it);
@ -7004,7 +7016,7 @@ _elm_genlist_item_next_get(const Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
do it = ELM_GEN_ITEM_NEXT(it);
while (it && sd->filter && !_item_filtered_get(it));
while (it && sd->filter && !_item_filtered_get(it, sd));
return EO_OBJ(it);
}
@ -7015,7 +7027,7 @@ _elm_genlist_item_prev_get(const Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
do it = ELM_GEN_ITEM_PREV(it);
while (it && sd->filter && !_item_filtered_get(it));
while (it && sd->filter && !_item_filtered_get(it, sd));
return EO_OBJ(it);
}
@ -7286,7 +7298,7 @@ _elm_genlist_item_coordinates_calc(Elm_Gen_Item *it,
sd->scroll_to_type = type;
it->item->show_me = EINA_TRUE;
_add_calc_job(sd);
efl_canvas_group_change(sd->obj);
return EINA_FALSE;
}
@ -7858,7 +7870,7 @@ _filter_item_internal(Elm_Gen_Item *it)
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
if (sd->filter_data)
{
if ((it->parent && !_item_filtered_get(it->parent)) ||
if ((it->parent && !_item_filtered_get(it->parent, sd)) ||
(it->itc->func.filter_get &&
!it->itc->func.filter_get(
(void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)),
@ -7877,11 +7889,11 @@ _filter_item_internal(Elm_Gen_Item *it)
// Returns true if the item is not filtered out, but remains visible.
static Eina_Bool
_item_filtered_get(Elm_Gen_Item *it)
_item_filtered_get(Elm_Gen_Item *it, Elm_Genlist_Data *sd)
{
Eina_List *l;
if (!it) return EINA_FALSE;
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
/* no filter exists: item will always be visible */
if (!sd->filter_data) return EINA_TRUE;
if (!it->filtered)
{
l = eina_list_data_find_list(sd->filter_queue, it);
@ -7902,10 +7914,10 @@ _item_filtered_get(Elm_Gen_Item *it)
_filter_item_internal(it);
if (it->item->block)
it->item->block->changed = EINA_TRUE;
_add_calc_job(sd);
efl_canvas_group_change(sd->obj);
sd->need_calc = EINA_TRUE;
}
if (!it->hide) return EINA_TRUE;
return EINA_FALSE;
return !it->hide;
}
static int
@ -7961,7 +7973,7 @@ _item_filter_enterer(void *data)
if (wakeup)
{
// wake up mainloop
_add_calc_job(sd);
efl_canvas_group_change(sd->obj);
}
if (ok == ECORE_CALLBACK_CANCEL)
{
@ -8002,6 +8014,8 @@ _elm_genlist_filter_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, void *filter_
sd->filter_queue = eina_list_append(sd->filter_queue, it);
}
itb->changed = EINA_TRUE;
evas_object_smart_changed(obj);
sd->need_calc = EINA_TRUE;
}
else
{
@ -8013,10 +8027,11 @@ _elm_genlist_filter_set(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, void *filter_
}
}
}
_calc_job(sd->obj);
sd->queue_filter_enterer = ecore_idle_enterer_add(_item_filter_enterer,
sd->obj);
if (!sd->filter_queue)
efl_event_callback_legacy_call(sd->obj, ELM_GENLIST_EVENT_FILTER_DONE, NULL);
else
sd->queue_filter_enterer = ecore_idle_enterer_add(_item_filter_enterer,
sd->obj);
}
static Eina_Bool
@ -8028,7 +8043,7 @@ _filter_iterator_next(Elm_Genlist_Filter *iter, void **data)
{
item = ELM_GENLIST_FILTER_ITERATOR_ITEM_GET(iter->current, Elm_Gen_Item);
iter->current = iter->current->next;
if (_item_filtered_get(item))
if (_item_filtered_get(item, item->item->block->sd))
{
if (data)
*data = EO_OBJ(item);
@ -8267,7 +8282,7 @@ _elm_genlist_decorate_mode_set(Eo *obj, Elm_Genlist_Data *sd, Eina_Bool decorate
}
}
_add_calc_job(sd);
efl_canvas_group_change(sd->obj);
}
EOLIAN static void
@ -8413,7 +8428,7 @@ _flip_job(void *data)
it->flipped = EINA_TRUE;
it->item->nocache = EINA_TRUE;
_add_calc_job(sd);
efl_canvas_group_change(sd->obj);
}
EOLIAN static void

View File

@ -55,7 +55,6 @@ struct _Elm_Genlist_Data
Elm_Object_Item *last_selected_item;
Elm_Object_Item *focused_item; /**< a focused item by keypad arrow or mouse. This is set to NULL if widget looses focus. */
Elm_Object_Item *last_focused_item; /**< This records the last focused item when widget looses focus. This is required to set the focus on last focused item when widgets gets focus. */
Ecore_Job *calc_job;
int walking;
int minw, minh;
unsigned int item_count;
@ -206,6 +205,7 @@ struct _Elm_Genlist_Data
Eina_Bool tree_effect_animator : 1;
Eina_Bool pin_item_top : 1;
Eina_Bool need_calc : 1; /* _calc_job() must be called in group_calc */
};
typedef struct _Item_Block Item_Block;
@ -253,6 +253,7 @@ struct Elm_Gen_Item_Type
Eina_Bool queued : 1;
Eina_Bool before : 1;
Eina_Bool show_me : 1;
Eina_Bool unfocusable : 1; /* item is not focusable; propagate to content */
};
struct _Item_Block

View File

@ -1264,10 +1264,9 @@ object_text_font_cache_dir_add(char *dir)
char *p;
fn->type = 0;
strcpy(tmp2, file);
p = strrchr(tmp2, '.');
if (p) *p = 0;
fn->simple.name = eina_stringshare_add(tmp2);
p = strrchr(file, '.');
if (p) fn->simple.name = eina_stringshare_add_length(file, p - file);
else fn->simple.name = eina_stringshare_add(file);
eina_file_path_join(tmp2, PATH_MAX, dir, file);
fn->path = eina_stringshare_add(tmp2);
fd->fonts = eina_list_append(fd->fonts, fn);

View File

@ -288,6 +288,98 @@ EFL_START_TEST(ecore_test_timer_in_order)
}
EFL_END_TEST
EFL_START_TEST(ecore_test_timer_iteration)
{
Ecore_Timer *timer;
count = 0;
/* verify that timers expire after exactly one loop iteration */
ecore_timer_add(0, _timer_cb, (void *) 1);
ecore_main_loop_iterate();
/* timers should not expire for one loop iteration */
ck_assert_int_eq(count, 0);
ecore_main_loop_iterate();
/* timers should expire after one loop iteration */
ck_assert_int_eq(count, 1);
/* verify multiple timer expiration in single mainloop iteration */
ecore_timer_add(0, _timer_cb, (void *) 2);
ecore_timer_add(0, _timer_cb, (void *) 3);
ecore_main_loop_iterate();
/* timers should not expire for one loop iteration */
ck_assert_int_eq(count, 1);
ecore_timer_add(0, _timer_cb, (void *) 4);
ecore_main_loop_iterate();
/* all pending and instantiated timers should expire after exactly one loop iteration */
ck_assert_int_eq(count, 3);
ecore_main_loop_iterate();
/* this should not interfere with successive timer processing */
ck_assert_int_eq(count, 4);
/* verify out-of-order timer processing solely based on timer times */
timer = ecore_timer_add(1, _timer_cb, (void *) 6);
ecore_main_loop_iterate();
ck_assert_int_eq(count, 4);
ecore_timer_add(0, _timer_cb, (void *) 5);
ecore_main_loop_iterate();
ck_assert_int_eq(count, 4);
/* timer should expire after exactly 2 iterations */
ecore_main_loop_iterate();
ck_assert_int_eq(count, 5);
ecore_timer_interval_set(timer, 0);
ecore_timer_reset(timer);
/* timer should expire after exactly 2 iterations since it becomes un-instantiated now */
ecore_main_loop_iterate();
ecore_main_loop_iterate();
ck_assert_int_eq(count, 6);
}
EFL_END_TEST
static Eina_Bool
_recursion()
{
Ecore_Timer *timer;
/* verify multiple timer expiration in single mainloop iteration */
ecore_timer_add(0, _timer_cb, (void *) 2);
ecore_timer_add(0, _timer_cb, (void *) 3);
ecore_main_loop_iterate();
/* timers should not expire for one loop iteration */
ck_assert_int_eq(count, 1);
ecore_timer_add(0, _timer_cb, (void *) 4);
ecore_main_loop_iterate();
/* all pending and instantiated timers should expire after exactly one loop iteration */
ck_assert_int_eq(count, 3);
ecore_main_loop_iterate();
/* this should not interfere with successive timer processing */
ck_assert_int_eq(count, 4);
/* verify out-of-order timer processing solely based on timer times */
timer = ecore_timer_add(1, _timer_cb, (void *) 6);
ecore_main_loop_iterate();
ck_assert_int_eq(count, 4);
ecore_timer_add(0, _timer_cb, (void *) 5);
ecore_main_loop_iterate();
ck_assert_int_eq(count, 4);
/* timer should expire after exactly 2 iterations */
ecore_main_loop_iterate();
ck_assert_int_eq(count, 5);
ecore_timer_interval_set(timer, 0);
ecore_timer_reset(timer);
/* timer should expire after exactly 2 iterations since it becomes un-instantiated now */
ecore_main_loop_iterate();
ecore_main_loop_iterate();
ck_assert_int_eq(count, 6);
return EINA_FALSE;
}
EFL_START_TEST(ecore_test_timer_recursion)
{
count = 1;
ecore_timer_add(0, _recursion, NULL);
ecore_main_loop_begin();
ck_assert_int_eq(count, 6);
}
EFL_END_TEST
void ecore_test_timer(TCase *tc)
{
tcase_add_test(tc, ecore_test_timers);
@ -295,4 +387,6 @@ void ecore_test_timer(TCase *tc)
tcase_add_test(tc, ecore_test_timer_valid_callbackfunc);
tcase_add_test(tc, ecore_test_ecore_main_loop_timer);
tcase_add_test(tc, ecore_test_timer_in_order);
tcase_add_test(tc, ecore_test_timer_iteration);
tcase_add_test(tc, ecore_test_timer_recursion);
}

View File

@ -71,6 +71,86 @@ EFL_START_TEST(efl_app_test_loop_timer_invalid)
}
EFL_END_TEST
static int count = 0;
static void
_timer_cb(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED)
{
count++;
}
static void
array_clean(Eina_Array *arr)
{
Eo *t;
while ((t = eina_array_pop(arr)))
efl_del(t);
}
EFL_START_TEST(efl_loop_test_loop_timer_iteration)
{
Eo *t, *loop;
Eina_Array *arr;
loop = efl_main_loop_get();
count = 0;
arr = eina_array_new(5);
#define TIMER(duration) \
t = efl_add(EFL_LOOP_TIMER_CLASS, loop, \
efl_loop_timer_interval_set(efl_added, (duration)), \
efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TIMER_TICK, _timer_cb, NULL) \
); \
eina_array_push(arr, t)
/* verify that timers expire after exactly one loop iteration */
TIMER(0);
efl_loop_iterate(loop);
/* timers should not expire for one loop iteration */
ck_assert_int_eq(count, 0);
efl_loop_iterate(loop);
/* timers should expire after one loop iteration */
ck_assert_int_eq(count, 1);
array_clean(arr);
count = 0;
/* verify multiple timer expiration in single mainloop iteration */
TIMER(0);
TIMER(0);
efl_loop_iterate(loop);
/* timers should not expire for one loop iteration */
ck_assert_int_eq(count, 0);
TIMER(0);
efl_loop_iterate(loop);
/* all pending and instantiated timers should expire after exactly one loop iteration */
ck_assert_int_eq(count, 2);
efl_loop_iterate(loop);
/* this should not interfere with successive timer processing */
ck_assert_int_eq(count, 5);
array_clean(arr);
count = 0;
/* verify out-of-order timer processing solely based on timer times */
TIMER(1);
efl_loop_iterate(loop);
ck_assert_int_eq(count, 0);
TIMER(0);
efl_loop_iterate(loop);
ck_assert_int_eq(count, 0);
/* timer should expire after exactly 2 iterations */
efl_loop_iterate(loop);
ck_assert_int_eq(count, 1);
efl_loop_timer_interval_set(eina_array_data_get(arr, 0), 0);
efl_loop_timer_reset(eina_array_data_get(arr, 0));
/* timer should expire after exactly 2 iterations since it becomes un-instantiated now */
efl_loop_iterate(loop);
efl_loop_iterate(loop);
ck_assert_int_eq(count, 4);
array_clean(arr);
}
EFL_END_TEST
void efl_app_test_efl_loop_timer(TCase *tc EINA_UNUSED)
{
/* XXX: this seems a silly test - that we del the loop object?
@ -78,4 +158,5 @@ void efl_app_test_efl_loop_timer(TCase *tc EINA_UNUSED)
*/
tcase_add_test(tc, efl_app_test_loop_timer_invalid);
tcase_add_test(tc, efl_loop_test_loop_timer_iteration);
}

View File

@ -336,7 +336,7 @@ EFL_START_TEST(eina_log_level_indexes)
EINA_LOG(d, -1, "Negative index message");
fail_if(ctx.did);
}
#ifdef EINA_LOG_LEVEL_MAXIMUM
if (6 <= maxlevel)
{
// Displayed only if user sets level 6 or higher
@ -345,7 +345,7 @@ EFL_START_TEST(eina_log_level_indexes)
EINA_LOG(d, 6, "Higher level debug");
fail_unless(ctx.did);
}
#endif
if (5 <= maxlevel)
{
eina_log_domain_level_set("Levels", 5);

View File

@ -68,7 +68,6 @@ EFL_START_TEST(efl_config_eoapi)
CONFIG_CHKD(scroll_thumbscroll_acceleration_time_limit, 0);
CONFIG_CHKD(scroll_thumbscroll_acceleration_weight, 0);
CONFIG_CHKE(focus_autoscroll_mode, EFL_UI_FOCUS_AUTOSCROLL_MODE_NONE, "none");
CONFIG_CHKE(slider_indicator_visible_mode, EFL_UI_SLIDER_INDICATOR_VISIBLE_MODE_ALWAYS, "always");
CONFIG_CHKD(longpress_timeout, 0);
CONFIG_CHKE(softcursor_mode, EFL_UI_SOFTCURSOR_MODE_ON, "on");
CONFIG_CHKD(tooltip_delay, 0);

View File

@ -134,6 +134,15 @@ _item_content_get(void *data EINA_UNUSED, Evas_Object *obj, const char *part EIN
return ic;
}
static char *
_item_text_get(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *part)
{
char buf[128];
/* just some random-ish (not really) text */
snprintf(buf, sizeof(buf), "%p", part);
return strdup(buf);
}
EFL_START_TEST(elm_genlist_test_item_content)
{
Elm_Genlist_Item_Class *gtc;
@ -383,6 +392,7 @@ EFL_START_TEST(elm_genlist_test_item_destroy)
EFL_END_TEST
#define NUM_TREE_ITEMS 10
#define GL_ITEM_SIZE_ISH 30
static Evas_Object *
genlist_tree_test_content_get(void *data EINA_UNUSED, Evas_Object *obj, const char *part)
@ -499,6 +509,7 @@ EFL_START_TEST(elm_genlist_test_tree_expand)
evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_weight_set(win, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_genlist_item_append(genlist, &itc,
NULL/* item data */, NULL/* parent */,
ELM_GENLIST_ITEM_TREE, NULL/* func */,
@ -510,9 +521,10 @@ EFL_START_TEST(elm_genlist_test_tree_expand)
NULL/* func data */);
evas_object_show(genlist);
evas_object_resize(genlist, 100, 10 + 10 * NUM_TREE_ITEMS);
evas_object_resize(genlist, 100, 10 + GL_ITEM_SIZE_ISH * NUM_TREE_ITEMS);
evas_object_show(win);
evas_object_resize(win, 100, 10 + 10 * NUM_TREE_ITEMS);
evas_object_resize(win, 100, 10 + GL_ITEM_SIZE_ISH * NUM_TREE_ITEMS);
ecore_main_loop_begin();
}
EFL_END_TEST
@ -560,6 +572,176 @@ EFL_START_TEST(elm_genlist_test_focus_state)
}
EFL_END_TEST
/* keep in sync with elm_genlist.c value */
#define MAX_ITEMS_PER_BLOCK 32
EFL_START_TEST(elm_genlist_test_events)
{
unsigned int i, called[10] = {0};
Eina_Bool norender = EINA_FALSE;
/* need focus for item focus tests */
win = win_add_focused(NULL, "genlist", ELM_WIN_BASIC);
itc.func.text_get = _item_text_get;
genlist = elm_genlist_add(win);
elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
for (i = 0; i < 2 * MAX_ITEMS_PER_BLOCK; i++)
elm_genlist_item_append(genlist, &itc,
NULL/* item data */, NULL/* parent */,
0, NULL/* func */,
NULL/* func data */);
/* show 10ish items */
evas_object_resize(genlist, 200, 10 + GL_ITEM_SIZE_ISH * 10);
evas_object_show(genlist);
evas_object_show(win);
evas_object_resize(win, 200, 10 + GL_ITEM_SIZE_ISH * 10);
get_me_to_those_events(genlist);
/* add callbacks only for the name array passed,
* verify that each callback is triggered based on event callback type
* remove callbacks so they don't break successive testing
* note: order is not tested or useful
*/
#define CB_TEST(namearray, ev_func, ...) \
do { \
const char **names = namearray; \
memset(called, 0, sizeof(called)); \
norender = EINA_FALSE; \
for (i = 0; *names; i++, names++) \
evas_object_smart_callback_add(genlist, *names, ev_func, &(called[i])); \
__VA_ARGS__ \
if (!norender) \
get_me_to_those_events(genlist); \
for (i = 0, names = namearray; *names; i++, names++) \
{ \
evas_object_smart_callback_del_full(genlist, *names, ev_func, &(called[i])); \
if (!called[i]) fprintf(stderr, "GENLIST EVENT TEST ERROR: \"%s\" failed to trigger as expected!\n", namearray[i]); \
if (ev_func == event_callback_that_increments_an_int_when_called) \
ck_assert_int_ge(called[i], 1); \
else \
ck_assert_int_eq(called[i], 1); \
} \
} while (0)
#define NAMEARRAY(...) \
(const char*[]){__VA_ARGS__, NULL}
/* first item: double click ->
* "activated" + "clicked,double" + "selected" + "highlighted" */
CB_TEST(NAMEARRAY("activated", "clicked,double", "selected", "highlighted"),
event_callback_single_call_int_data,
click_object_at_flags(genlist, 5, 5, EVAS_BUTTON_DOUBLE_CLICK);
);
/* first item: right click ->
* "clicked,right" */
CB_TEST(
NAMEARRAY("clicked,right"),
event_callback_single_call_int_data,
Evas *e = evas_object_evas_get(genlist);
norender = EINA_TRUE;
evas_event_feed_mouse_move(e, 5, 5, 0, NULL);
/* no util function for this since we never use right click */
evas_event_feed_mouse_down(e, 3, 0, 0, NULL);
evas_event_feed_mouse_up(e, 3, 0, 0, NULL);
);
/* some other item:
* click ->
* "unselected" + "unhighlighted" + "item,unfocused" on first item
* "pressed" + "released" + "item,focused" on other item */
CB_TEST(
NAMEARRAY("unselected", "unhighlighted", "pressed", "released", "item,focused", "item,unfocused"),
event_callback_single_call_int_data,
/* click on some other random item to trigger different selection/highlight */
click_object_at(genlist, 5, 50);
);
/* wheel ->
* "realized" on unrealized items
* "unrealized" on first item */
CB_TEST(
NAMEARRAY("realized", "unrealized"),
event_callback_that_increments_an_int_when_called,
/* disable animations to avoid having to wait an indeterminate amount of time for scrolling */
elm_config_scroll_animation_disabled_set(EINA_TRUE);
/* wheel to trigger realize/unrealize */
wheel_object_at(genlist, 50, 50, 0, 1);
/* re-enable animations before failure to avoid triggering cascading test failures */
elm_config_scroll_animation_disabled_set(EINA_FALSE);
);
/* filter_set ->
* "filter,done"
*/
CB_TEST(
NAMEARRAY("filter,done"),
event_callback_single_call_int_data,
elm_genlist_filter_set(genlist, "2");
);
elm_genlist_filter_set(genlist, NULL);
/* simple drag ->
* "swipe" + "drag,start,right" + "drag,stop"
* also multiple "drag" events
*/
evas_object_smart_callback_add(genlist, "drag", event_callback_that_increments_an_int_when_called, &called[5]);
CB_TEST(
NAMEARRAY("swipe", "drag,start,right", "drag,stop"),
event_callback_single_call_int_data,
click_object_at(genlist, 5, 50);
drag_object(genlist, 5, 50, 150, 0, EINA_FALSE);
);
evas_object_smart_callback_del_full(genlist, "drag", event_callback_that_increments_an_int_when_called, &called[5]);
/* there should be DRAG_OBJECT_NUM_MOVES - 1 "drag" events */
ck_assert_int_eq(called[5], DRAG_OBJECT_NUM_MOVES - 1);
/* continuous simple drags ->
* "drag,start,left", "drag,start,up", "drag,start,down"
*/
evas_object_smart_callback_add(genlist, "drag,stop", event_callback_that_increments_an_int_when_called, &called[3]);
CB_TEST(
NAMEARRAY("drag,start,left", "drag,start,up", "drag,start,down"),
event_callback_single_call_int_data,
/* left */
click_object_at(genlist, 155, 50);
drag_object(genlist, 155, 50, -150, 0, EINA_FALSE);
/* down */
click_object_at(genlist, 5, 50);
drag_object(genlist, 5, 50, 0, 100, EINA_FALSE);
/* up */
click_object_at(genlist, 5, 150);
drag_object(genlist, 5, 150, 0, -100, EINA_FALSE);
);
evas_object_smart_callback_del_full(genlist, "drag", event_callback_that_increments_an_int_when_called, &called[3]);
ck_assert_int_eq(called[3], DRAG_OBJECT_NUM_MOVES - 1);
/* intensive drag down ->
* "longpressed" + "moved" + "moved,after"
* also "index,update" on all affected items
*/
evas_object_smart_callback_add(genlist, "index,update", event_callback_that_increments_an_int_when_called, &called[3]);
CB_TEST(
/* "moved,before" can only be triggered on the first item and is a bit finnicky/unreliable
* to trigger in unit tests so it's being ignored for now
*/
NAMEARRAY("longpressed", "moved", "moved,after"),
event_callback_single_call_int_data,
double lp = elm_genlist_longpress_timeout_get(genlist);
elm_genlist_reorder_mode_set(genlist, EINA_TRUE);
elm_genlist_longpress_timeout_set(genlist, 0);
click_object_at(genlist, 5, 5);
drag_object(genlist, 5, 5, 0, 90, EINA_TRUE);
elm_genlist_reorder_mode_set(genlist, EINA_FALSE);
elm_genlist_longpress_timeout_set(genlist, lp);
);
evas_object_smart_callback_del_full(genlist, "index,update", event_callback_that_increments_an_int_when_called, &called[3]);
/* at minimum, 2 items should have been changed */
ck_assert_int_ge(called[3], 2);
}
EFL_END_TEST
void elm_test_genlist(TCase *tc)
{
tcase_add_test(tc, elm_genlist_test_legacy_type_check);
@ -575,4 +757,6 @@ void elm_test_genlist(TCase *tc)
tcase_add_test(tc, elm_genlist_test_focus_state);
tcase_add_test(tc, elm_genlist_test_tree_expand);
tcase_add_test(tc, elm_genlist_test_events);
}

View File

@ -24,17 +24,16 @@ Eina_Bool abort_on_warnings = EINA_FALSE;
void elm_test_init(TCase *tc);
static char *args[] = { "exe" };
SUITE_INIT(elm)
{
char *args[] = { "exe" };
ck_assert_int_eq(elm_init(1, args), 1);
}
void
_elm2_suite_init(void)
{
char *args[] = { "exe" };
if (getpid() != main_pid)
{
if (abort_on_warnings)
@ -430,23 +429,29 @@ attempt_to_find_the_right_point_for_mouse_positioning(Eo *obj, int dir)
}
static void
click_object_internal(Eo *obj, int dir)
click_object_internal(Eo *obj, int dir, int flags)
{
Evas *e = evas_object_evas_get(obj);
Eina_Position2D pos = attempt_to_find_the_right_point_for_mouse_positioning(obj, dir);
evas_event_feed_mouse_move(e, pos.x, pos.y, 0, NULL);
evas_event_feed_mouse_down(e, 1, 0, 0, NULL);
evas_event_feed_mouse_down(e, 1, flags, 0, NULL);
evas_event_feed_mouse_up(e, 1, 0, 0, NULL);
}
void
click_object(Eo *obj)
{
click_object_internal(obj, NONE);
click_object_internal(obj, NONE, 0);
}
void
click_part(Eo *obj, const char *part)
click_object_flags(Eo *obj, int flags)
{
click_object_internal(obj, NONE, flags);
}
void
click_part_flags(Eo *obj, const char *part, int flags)
{
Efl_Part *part_obj = efl_ref(efl_part(obj, part));
Eo *content;
@ -466,13 +471,19 @@ click_part(Eo *obj, const char *part)
else if (strstr(part, "bottom"))
dir |= BOTTOM;
}
click_object_internal(content, dir);
click_object_internal(content, dir, flags);
if (efl_isa(content, EFL_LAYOUT_SIGNAL_INTERFACE))
edje_object_message_signal_process(content);
edje_object_message_signal_process(obj);
efl_unref(part_obj);
}
void
click_part(Eo *obj, const char *part)
{
click_part_flags(obj, part, 0);
}
static void
wheel_object_internal(Eo *obj, int dir, Eina_Bool horiz, Eina_Bool down)
{
@ -523,6 +534,14 @@ event_callback_single_call_int_data(void *data, Evas_Object *obj EINA_UNUSED, vo
*called = 1;
}
void
event_callback_that_increments_an_int_when_called(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
int *called = data;
*called += 1;
}
void
event_callback_that_quits_the_main_loop_when_called()
{
@ -538,6 +557,15 @@ click_object_at(Eo *obj, int x, int y)
evas_event_feed_mouse_up(e, 1, 0, 0, NULL);
}
void
click_object_at_flags(Eo *obj, int x, int y, int flags)
{
Evas *e = evas_object_evas_get(obj);
evas_event_feed_mouse_move(e, x, y, 0, NULL);
evas_event_feed_mouse_down(e, 1, flags, 0, NULL);
evas_event_feed_mouse_up(e, 1, 0, 0, NULL);
}
void
wheel_object_at(Eo *obj, int x, int y, Eina_Bool horiz, Eina_Bool down)
{
@ -545,3 +573,27 @@ wheel_object_at(Eo *obj, int x, int y, Eina_Bool horiz, Eina_Bool down)
evas_event_feed_mouse_move(e, x, y, 0, NULL);
evas_event_feed_mouse_wheel(e, horiz, down, 0, NULL);
}
void
drag_object(Eo *obj, int x, int y, int dx, int dy, Eina_Bool iterate)
{
Evas *e = evas_object_evas_get(obj);
int i;
evas_event_feed_mouse_move(e, x, y, 0, NULL);
evas_event_feed_mouse_down(e, 1, 0, 0, NULL);
if (iterate)
{
/* iterate twice to trigger timers */
ecore_main_loop_iterate();
ecore_main_loop_iterate();
}
/* create DRAG_OBJECT_NUM_MOVES move events distinct from up/down */
for (i = 0; i < DRAG_OBJECT_NUM_MOVES; i++)
{
evas_event_feed_mouse_move(e, x + (i * dx / DRAG_OBJECT_NUM_MOVES), y + (i * dy / DRAG_OBJECT_NUM_MOVES), 0, NULL);
/* also trigger smart calc if we're iterating just in case that's important */
evas_smart_objects_calculate(e);
}
evas_event_feed_mouse_move(e, x + dx, y + dy, 0, NULL);
evas_event_feed_mouse_up(e, 1, 0, 0, NULL);
}

View File

@ -3,6 +3,8 @@
#include <Evas.h>
#define DRAG_OBJECT_NUM_MOVES 4
int suite_setup(Eina_Bool legacy);
void _elm2_suite_init(void);
void _elm_suite_shutdown(void);
@ -12,11 +14,16 @@ void fail_on_errors_setup(void);
void get_me_to_those_events(Eo *obj);
void click_object(Eo *obj);
void click_object_flags(Eo *obj, int flags);
void click_part(Eo *obj, const char *part);
void click_part_flags(Eo *obj, const char *part, int flags);
void click_object_at(Eo *obj, int x, int y);
void click_object_at_flags(Eo *obj, int x, int y, int flags);
void drag_object(Eo *obj, int x, int y, int dx, int dy, Eina_Bool iterate);
void wheel_object(Eo *obj, Eina_Bool horiz, Eina_Bool down);
void wheel_part(Eo *obj, const char *part, Eina_Bool horiz, Eina_Bool down);
void wheel_object_at(Eo *obj, int x, int y, Eina_Bool horiz, Eina_Bool down);
void event_callback_single_call_int_data(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED);
void event_callback_that_quits_the_main_loop_when_called();
void event_callback_that_increments_an_int_when_called(void *data, Evas_Object *obj, void *event_info);
#endif