diff --git a/src/lib/elementary/efl_ui_text.c b/src/lib/elementary/efl_ui_text.c index f9a575f87a..7a90a63827 100644 --- a/src/lib/elementary/efl_ui_text.c +++ b/src/lib/elementary/efl_ui_text.c @@ -47,7 +47,6 @@ struct _Efl_Ui_Text_Data Evas_Object *start_handler; Evas_Object *end_handler; Ecore_Job *deferred_decoration_job; - Ecore_Timer *longpress_timer; Ecore_Timer *delay_write; /* for deferred appending */ Ecore_Idler *append_text_idler; @@ -1427,8 +1426,6 @@ _long_press_cb(void *data, const Efl_Event *ev EINA_UNUSED) _menu_call(data); sd->long_pressed = EINA_TRUE; - - sd->longpress_timer = NULL; } static void @@ -1522,7 +1519,8 @@ _mouse_up_cb(void *data, if (sd->disabled) return; if (ev->button == 1) { - ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del); + efl_input_clickable_longpress_abort(data, 1); + /* Since context menu disabled flag was checked at long press start while mouse * down, hence the same should be checked at mouse up from a long press * as well */ @@ -1563,6 +1561,7 @@ _mouse_move_cb(void *data, void *event_info) { Evas_Event_Mouse_Move *ev = event_info; + Evas_Coord dx, dy; EFL_UI_TEXT_DATA_GET(data, sd); @@ -1592,38 +1591,18 @@ _mouse_move_cb(void *data, { if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) { - ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del); - } - else if (sd->longpress_timer) - { - Evas_Coord dx, dy; - - dx = sd->downx - ev->cur.canvas.x; - dx *= dx; - dy = sd->downy - ev->cur.canvas.y; - dy *= dy; - if ((dx + dy) > - ((_elm_config->finger_size / 2) * - (_elm_config->finger_size / 2))) - { - ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del); - } + efl_input_clickable_longpress_abort(data, 1); } } - else if (sd->longpress_timer) - { - Evas_Coord dx, dy; - dx = sd->downx - ev->cur.canvas.x; - dx *= dx; - dy = sd->downy - ev->cur.canvas.y; - dy *= dy; - if ((dx + dy) > - ((_elm_config->finger_size / 2) * - (_elm_config->finger_size / 2))) - { - ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del); - } + dx = sd->downx - ev->cur.canvas.x; + dx *= dx; + dy = sd->downy - ev->cur.canvas.y; + dy *= dy; + if ((dx + dy) > ((_elm_config->finger_size / 2) * + (_elm_config->finger_size / 2))) + { + efl_input_clickable_longpress_abort(data, 1); } } @@ -1716,7 +1695,7 @@ _selection_handlers_offset_calc(Evas_Object *obj, Evas_Object *handler) sd->oy = pos.y + cy + (ch / 2); } - ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del); + efl_input_clickable_longpress_abort(obj, 1); sd->long_pressed = EINA_FALSE; } @@ -1799,7 +1778,7 @@ _start_handler_mouse_move_cb(void *data, efl_text_cursor_position_set(sd->text_obj, efl_text_cursor_get(sd->text_obj, EFL_TEXT_CURSOR_GET_TYPE_MAIN), pos); - ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del); + efl_input_clickable_longpress_abort(data, 1); sd->long_pressed = EINA_FALSE; } @@ -1879,7 +1858,7 @@ _end_handler_mouse_move_cb(void *data, pos = efl_text_cursor_position_get(sd->text_obj, sd->sel_handler_cursor); /* Set the main cursor. */ efl_text_cursor_position_set(sd->text_obj, efl_text_cursor_get(data, EFL_TEXT_CURSOR_GET_TYPE_MAIN), pos); - ELM_SAFE_FREE(sd->longpress_timer, ecore_timer_del); + efl_input_clickable_longpress_abort(data, 1); sd->long_pressed = EINA_FALSE; } @@ -2266,7 +2245,6 @@ _efl_ui_text_efl_object_destructor(Eo *obj, Efl_Ui_Text_Data *sd) ELM_SAFE_FREE(sd->append_text_left, free); sd->append_text_idler = NULL; } - ecore_timer_del(sd->longpress_timer); EINA_LIST_FREE(sd->items, it) { eina_stringshare_del(it->label); diff --git a/src/lib/evas/canvas/efl_input_clickable.c b/src/lib/evas/canvas/efl_input_clickable.c index fb6c3fe457..cc248184bd 100644 --- a/src/lib/evas/canvas/efl_input_clickable.c +++ b/src/lib/evas/canvas/efl_input_clickable.c @@ -118,4 +118,19 @@ _efl_input_clickable_button_state_reset(Eo *obj EINA_UNUSED, Efl_Input_Clickable state->pressed = EINA_FALSE; } +EOLIAN static void +_efl_input_clickable_longpress_abort(Eo *obj EINA_UNUSED, Efl_Input_Clickable_Data *pd, unsigned int button) +{ + Button_State *state; + EINA_SAFETY_ON_FALSE_RETURN(button < 3); + + state = &pd->state[button]; + EINA_SAFETY_ON_NULL_RETURN(state); + + INF("Widget %s,%p - longpress is aborted(%d)", efl_class_name_get(obj), obj, button); + + if (state->timer) + efl_del(state->timer); + state->timer = NULL; +} #include "efl_input_clickable.eo.c" diff --git a/src/lib/evas/canvas/efl_input_clickable.eo b/src/lib/evas/canvas/efl_input_clickable.eo index 14ca084d37..7a7f05bfb3 100644 --- a/src/lib/evas/canvas/efl_input_clickable.eo +++ b/src/lib/evas/canvas/efl_input_clickable.eo @@ -36,6 +36,15 @@ mixin @beta Efl.Input.Clickable button : uint; } } + longpress_abort @protected { + [[This aborts ongoing longpress event. + + That is, this will stop the timer for longpress. + ]] + params { + button : uint; + } + } } events { clicked: Efl.Input.Clickable_Clicked; [[Called when object is in sequence pressed and unpressed, by the primary button]] diff --git a/src/tests/elementary/spec/efl_test_clickable.c b/src/tests/elementary/spec/efl_test_clickable.c index 8051a8e3c1..9ac7e9c9fb 100644 --- a/src/tests/elementary/spec/efl_test_clickable.c +++ b/src/tests/elementary/spec/efl_test_clickable.c @@ -220,6 +220,33 @@ EFL_START_TEST(long_press_event) } EFL_END_TEST +EFL_START_TEST(long_press_abort) +{ + efl_event_callback_array_add(widget, clickable(), NULL); + down(1); + iterate_mainloop(0.1); + ck_assert_int_eq(event_caller.pressed, 1); + event_caller.pressed = 0; + assert_event_empty(); + efl_input_clickable_longpress_abort(widget, 1); + iterate_mainloop(2.0); + assert_event_empty(); + up(1); + iterate_mainloop(0.1); + ck_assert_int_eq(event_caller.clicked, 1); + event_caller.clicked = 0; + ck_assert_int_eq(event_caller.clicked_params.repeated, 0); + ck_assert_int_eq(event_caller.clicked_params.button, 1); + ck_assert_int_eq(event_caller.clicked_all, 1); + event_caller.clicked_all = 0; + ck_assert_int_eq(event_caller.clicked_all_params.repeated, 0); + ck_assert_int_eq(event_caller.clicked_all_params.button, 1); + ck_assert_int_eq(event_caller.unpressed, 1); + event_caller.unpressed = 0; + assert_event_empty(); +} +EFL_END_TEST + EFL_START_TEST(repeated_event) { efl_event_callback_array_add(widget, clickable(), NULL); @@ -254,5 +281,6 @@ efl_ui_clickable_behavior_test(TCase *tc) tcase_add_checked_fixture(tc, prepare_window, NULL); tcase_add_test(tc, simple_left_down_up); tcase_add_test(tc, long_press_event); + tcase_add_test(tc, long_press_abort); tcase_add_test(tc, repeated_event); }