Compare commits

...

8 Commits

Author SHA1 Message Date
Marcel Hollerbach 020cea923e ecore_evas_x: add safety check for data in converter
since the existance of seleciton manager, the converter callbacks from
ecore_x are expecting custom struct pointers. However, enlightenment
never updated to use the elm dnd API for client side usages. Which
results in the fact that sometimes, when a client sents Notify, and
e_dnd is active, that this converter is executed with the wrong data.

With this commit the data passed in is ensured to have the correct magic
number. The proper solution for this would either be registering the
correct converters in enlightenment, or update to elm_drag. However,
since the continues cried river over the last 5 days has raised enough
hydro power to add these changes. This leaves us with just one question:
How was it possible to generate so many messages about a problem that
can be solved in a fraction of charaters that have been written?

fixes <a-issue-that-was-never-created>

Differential Revision: https://phab.enlightenment.org/D11701
2020-04-14 11:56:29 +02:00
Marcel Hollerbach 96288c7683 ecore_evas_x: reject the promise instead of return
this is needed in order to tell the API user that this is not going to
be completed.

Differential Revision: https://phab.enlightenment.org/D11700
2020-04-14 11:56:15 +02:00
Marcel Hollerbach 0122f4c7b8 ecore_evas: add API for finding out if event is used
ecore_x_dnd_send_status can be used to indicate if a item can be dropped
on a client or not. However, we should only indicate that this can be
dropped, if there is a object we signaled that a drop is in.

Long story short: there is no assertion that after indicating that
things can be dropped, that a notify for the data is sent. A drag
implementation should always listen to a mouse up event, and abort the
drag if no further operations are sent.

Differential Revision: https://phab.enlightenment.org/D11699
2020-04-14 11:55:59 +02:00
Marcel Hollerbach be7ffe1142 elm_dnd: support target setting on none evas_objects
before this only worked for elm widgets. This however is the same
behaviour as in efl_ui_selection_manager.c. So this restores the
behaviour prior to selection_manager.

Differential Revision: https://phab.enlightenment.org/D11698
2020-04-14 11:55:41 +02:00
Marcel Hollerbach 5551a39d68 ecore_evas_x: allow parsing of links form the link list
this is needed in order to return the data the same way the legacy impl
did. This however has the annoying sideeffect that ecore_evas_x now
depends on efreet, and we had to change the build order.

Differential Revision: https://phab.enlightenment.org/D11697
2020-04-14 11:55:27 +02:00
Marcel Hollerbach 75b86bc548 build: fix libraries of efreet-mime -trash
the dependencies were simply wrong.

Differential Revision: https://phab.enlightenment.org/D11696
2020-04-14 11:55:11 +02:00
Marcel Hollerbach 8ad6a7e014 elm_dnd: complete the list of text types
the text types added here were present as "TEXT" in selection manager,
so add them here again.

Differential Revision: https://phab.enlightenment.org/D11684
2020-04-14 11:54:59 +02:00
Marcel Hollerbach 74f109e643 elm_slider: create timer for hiding later
_popup_show deletes the hide timer, hence we need to create the timer
later on, or this will not automatically hide the indicator.

Differential Revision: https://phab.enlightenment.org/D11679
2020-04-14 11:37:41 +02:00
9 changed files with 134 additions and 34 deletions

View File

@ -317,11 +317,11 @@ subprojects = [
['ecore_drm2' ,['drm'] , false, true, false, false, false, false, ['ecore'], ['libdrm']],
['ecore_cocoa' ,['cocoa'] , false, true, false, false, false, false, ['eina'], []],
['evas' ,[] , true, true, false, false, true, true, ['eina', 'efl', 'eo'], ['vg_common', 'libunibreak']],
['efreet' ,[] , false, true, false, false, true, false, ['eina', 'efl', 'eo'], []],
['ecore_input_evas' ,[] , false, true, false, false, false, false, ['eina', 'evas'], []],
['ecore_evas' ,[] , true, true, true, false, false, false, ['evas', 'ector'], []],
['ecore_imf' ,[] , true, true, false, false, false, false, ['eina'], []],
['embryo' ,[] , false, true, true, false, false, false, ['eina', 'efl', 'eo'], []],
['efreet' ,[] , false, true, false, false, true, false, ['eina', 'efl', 'eo'], []],
['eio' ,[] , false, true, false, false, true, true, ['eina', 'eet'], []],
['efreet' ,[] , false, false, true, false, false, false, ['eina', 'efl', 'eo'], []],
['ecore_imf_evas' ,[] , false, true, false, false, false, false, ['eina', 'efl', 'eo'], []],

View File

@ -5699,6 +5699,7 @@ ecore_evas_callback_drop_drop_set(Ecore_Evas *ee, Ecore_Evas_Drop_Cb cb)
typedef struct {
Eina_Array *available_mime_types;
Eina_Position2D pos;
Eina_Bool last_motion_was_used;
} Ecore_Evas_Active_Dnd;
static void
@ -5734,18 +5735,34 @@ ecore_evas_dnd_enter(Ecore_Evas *ee, unsigned int seat, Eina_Iterator *available
ee->func.fn_dnd_state_change(ee, seat, pos, EINA_TRUE);
}
EAPI void
EAPI Eina_Bool
ecore_evas_dnd_position_set(Ecore_Evas *ee, unsigned int seat, Eina_Position2D pos)
{
Ecore_Evas_Active_Dnd *dnd;
ECORE_EVAS_CHECK_GOTO(ee, err);
EINA_SAFETY_ON_NULL_GOTO(ee->active_drags, err);
dnd = eina_hash_find(ee->active_drags, &seat);
EINA_SAFETY_ON_NULL_GOTO(dnd, err);
dnd->pos = pos;
dnd->last_motion_was_used = EINA_FALSE;
if (ee->func.fn_dnd_motion)
ee->func.fn_dnd_motion(ee, seat, pos);
return dnd->last_motion_was_used;
err:
return EINA_FALSE;
}
EAPI void
ecore_evas_dnd_mark_motion_used(Ecore_Evas *ee, unsigned int seat)
{
Ecore_Evas_Active_Dnd *dnd;
ECORE_EVAS_CHECK(ee);
EINA_SAFETY_ON_NULL_RETURN(ee->active_drags);
dnd = eina_hash_find(ee->active_drags, &seat);
EINA_SAFETY_ON_NULL_RETURN(dnd);
dnd->pos = pos;
if (ee->func.fn_dnd_motion)
ee->func.fn_dnd_motion(ee, seat, pos);
dnd->last_motion_was_used = EINA_TRUE;
}
EAPI void

View File

@ -522,8 +522,8 @@ EAPI Eina_Bool ecore_evas_render(Ecore_Evas *ee);
EAPI Evas *ecore_evas_evas_new(Ecore_Evas *ee, int w, int h);
EAPI void ecore_evas_done(Ecore_Evas *ee, Eina_Bool single_window);
EAPI void ecore_evas_dnd_position_set(Ecore_Evas *ee, unsigned int seat, Eina_Position2D pos);
EAPI void ecore_evas_dnd_mark_motion_used(Ecore_Evas *ee, unsigned int seat);
EAPI Eina_Bool ecore_evas_dnd_position_set(Ecore_Evas *ee, unsigned int seat, Eina_Position2D pos);
EAPI void ecore_evas_dnd_leave(Ecore_Evas *ee, unsigned int seat, Eina_Position2D pos);
EAPI void ecore_evas_dnd_enter(Ecore_Evas *ee, unsigned int seat, Eina_Iterator *available_types, Eina_Position2D pos);
EAPI Eina_Position2D ecore_evas_dnd_pos_get(Ecore_Evas *ee, unsigned int seat);

View File

@ -85,12 +85,12 @@ pkgconfig.generate(efreet_mime_lib,
name : 'efreet-mime',
subdirs : package_version_name,
version : version_major + '.' + version_minor + '.' + version_micro,
libraries : [tmp_deps] + tmp_pub_deps,
libraries : efreet_pub_deps,
)
pkgconfig.generate(efreet_trash_lib,
name : 'efreet-trash',
subdirs : package_version_name,
version : version_major + '.' + version_minor + '.' + version_micro,
libraries : [tmp_deps] + tmp_pub_deps,
libraries : efreet_pub_deps,
)

View File

@ -9268,15 +9268,18 @@ _motion_cb(Ecore_Evas *ee, unsigned int seat, Eina_Position2D p)
{
target->currently_inside = EINA_FALSE;
efl_event_callback_call(target->obj, EFL_UI_DND_EVENT_DROP_LEFT, &ev);
ecore_evas_dnd_mark_motion_used(ee, seat);
}
else if (!target->currently_inside && inside)
{
target->currently_inside = EINA_TRUE;
efl_event_callback_call(target->obj, EFL_UI_DND_EVENT_DROP_ENTERED, &ev);
ecore_evas_dnd_mark_motion_used(ee, seat);
}
else if (target->currently_inside && inside)
{
efl_event_callback_call(target->obj, EFL_UI_DND_EVENT_DROP_POSITION_CHANGED, &ev);
ecore_evas_dnd_mark_motion_used(ee, seat);
}
eina_accessor_free(ev.available_types);
}
@ -9398,12 +9401,29 @@ _remove(void *data, void *gdata)
return EINA_TRUE;
}
static Efl_Ui_Win_Data*
_fetch_win_data_from_arbitary_obj(Efl_Canvas_Object *obj)
{
Efl_Ui_Win *win = efl_provider_find(obj, MY_CLASS);
if (!win)
{
Evas *e = evas_object_evas_get(obj);
Ecore_Evas *ee = ecore_evas_ecore_evas_get(e);
win = ecore_evas_data_get(ee, "elm_win");
}
EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
Efl_Ui_Win_Data *pd = efl_data_scope_safe_get(win, MY_CLASS);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd, NULL);
return pd;
}
void
_drop_event_register(Eo *obj)
{
Ui_Dnd_Target target = {obj, EINA_FALSE};
Efl_Ui_Win_Data *pd = efl_data_scope_safe_get(efl_provider_find(obj, MY_CLASS), MY_CLASS);
EINA_SAFETY_ON_NULL_RETURN(pd);
Efl_Ui_Win_Data *pd = _fetch_win_data_from_arbitary_obj(obj);
if (!pd) return;
eina_inarray_push(pd->drop_target, &target);
}
@ -9412,9 +9432,8 @@ void
_drop_event_unregister(Eo *obj)
{
int idx = -1;
Efl_Ui_Win_Data *pd;
pd = efl_data_scope_safe_get(efl_provider_find(obj, MY_CLASS), MY_CLASS);
Efl_Ui_Win_Data *pd = _fetch_win_data_from_arbitary_obj(obj);
if (!pd) return;
for (unsigned int i = 0; i < eina_inarray_count(pd->drop_target); ++i)
@ -9434,9 +9453,7 @@ _drop_event_unregister(Eo *obj)
void
_selection_changed_event_register(Eo *obj)
{
Efl_Ui_Win_Data *pd;
pd = efl_data_scope_safe_get(efl_provider_find(obj, MY_CLASS), MY_CLASS);
Efl_Ui_Win_Data *pd = _fetch_win_data_from_arbitary_obj(obj);
if (!pd) return;
eina_array_push(pd->selection_changed, obj);
@ -9444,9 +9461,7 @@ _selection_changed_event_register(Eo *obj)
void
_selection_changed_event_unregister(Eo *obj)
{
Efl_Ui_Win_Data *pd;
pd = efl_data_scope_safe_get(efl_provider_find(obj, MY_CLASS), MY_CLASS);
Efl_Ui_Win_Data *pd = _fetch_win_data_from_arbitary_obj(obj);
if (!pd) return;
eina_array_remove(pd->selection_changed, _remove, obj);

View File

@ -97,13 +97,30 @@ _deliver_content(Eo *obj, void *data, const Eina_Value value)
return EINA_VALUE_EMPTY;
}
static Efl_Ui_Win*
_fetch_win(Efl_Canvas_Object *obj)
{
Efl_Ui_Win *win = efl_provider_find(obj, EFL_UI_WIN_CLASS);
if (!win)
{
Evas *e = evas_object_evas_get(obj);
Ecore_Evas *ee = ecore_evas_ecore_evas_get(e);
win = ecore_evas_data_get(ee, "elm_win");
}
EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
return win;
}
static void
_drop_cb(void *data, const Efl_Event *ev)
{
Efl_Ui_Drop_Dropped_Event *event = ev->info;
Elm_Drop_Target *target = data;
target->action = _string_to_action(event->action);
efl_future_then(ev->object, efl_ui_dnd_drop_data_get(ev->object, _default_seat(ev->object), eina_array_iterator_new(target->mime_types)),
efl_future_then(ev->object, efl_ui_dnd_drop_data_get(elm_widget_is(ev->object) ? ev->object : _fetch_win(ev->object), _default_seat(ev->object), eina_array_iterator_new(target->mime_types)),
.success = _deliver_content,
.data = target
);
@ -133,7 +150,11 @@ _format_to_mime_array(Elm_Sel_Format format)
Eina_Array *ret = eina_array_new(10);
if (format & ELM_SEL_FORMAT_TEXT)
eina_array_push(ret, "text/plain;charset=utf-8");
{
eina_array_push(ret, "text/plain");
eina_array_push(ret, "text/plain;charset=utf-8");
eina_array_push(ret, "text/uri-list");
}
if (format & ELM_SEL_FORMAT_MARKUP)
eina_array_push(ret, "application/x-elementary-markup");
if (format & ELM_SEL_FORMAT_IMAGE)
@ -178,7 +199,7 @@ elm_drop_target_add(Evas_Object *obj, Elm_Sel_Format format,
target->format = format;
efl_event_callback_array_add(obj, drop_target_cb(), target);
_drop_event_register(obj); //this is ensuring that we are also supporting none widgets
if (!target_register)
target_register = eina_hash_pointer_new(NULL);
eina_hash_list_append(target_register, &obj, target);
@ -223,6 +244,7 @@ elm_drop_target_del(Evas_Object *obj, Elm_Sel_Format format,
efl_event_callback_array_del(obj, drop_target_cb(), eina_list_data_get(found));
eina_hash_list_remove(target_register, &obj, target);
eina_array_free(target->mime_types);
_drop_event_unregister(obj); //this is ensuring that we are also supporting none widgets
free(target);
}

View File

@ -630,9 +630,6 @@ _elm_slider_efl_ui_widget_widget_input_event_handler(Eo *obj, Elm_Slider_Data *s
else
_drag_down(obj, NULL, NULL, NULL);
efl_input_processed_set(ev, EINA_TRUE);
ELM_SAFE_FREE(sd->wheel_indicator_timer, ecore_timer_del);
sd->wheel_indicator_timer =
ecore_timer_add(0.5, _wheel_indicator_timer_cb, obj);
}
else return EINA_FALSE;
@ -640,6 +637,13 @@ _elm_slider_efl_ui_widget_widget_input_event_handler(Eo *obj, Elm_Slider_Data *s
_val_fetch(obj, EINA_TRUE);
evas_object_smart_changed(obj);
if (eo_event->desc == EFL_EVENT_POINTER_WHEEL)
{
ELM_SAFE_FREE(sd->wheel_indicator_timer, ecore_timer_del);
sd->wheel_indicator_timer =
ecore_timer_add(0.5, _wheel_indicator_timer_cb, obj);
}
return EINA_TRUE;
}

View File

@ -13,6 +13,7 @@
#include <Ecore_X.h>
#include <Ecore_X_Atoms.h>
#include <Efreet.h>
#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
# include <Evas_Engine_Software_X11.h>
@ -48,6 +49,8 @@
# endif
#endif /* ! _WIN32 */
#define ECORE_EVAS_X11_SELECTION 0x7F
#define EDBG(...) \
EINA_LOG(_ecore_evas_log_dom, EINA_LOG_LEVEL_DBG + 1, __VA_ARGS__);
@ -74,6 +77,7 @@ static Eina_Bool wm_exists;
typedef struct _Ecore_Evas_Engine_Data_X11 Ecore_Evas_Engine_Data_X11;
typedef struct {
EINA_MAGIC;
Ecore_Evas_Selection_Callbacks callbacks;
Ecore_Evas_Selection_Buffer buffer;
Ecore_Evas *ee;
@ -3858,17 +3862,40 @@ _create_deliveriy_content(unsigned long int size, const void *mem, const char *m
static void
_deliver_content(Ecore_Evas *ee, Ecore_Evas_Engine_Data_X11 *edata, Ecore_Evas_Selection_Buffer selection, Ecore_X_Event_Selection_Notify *ev)
{
Ecore_X_Selection_Data *x11_data = ev->data;
Eina_Content *result = NULL;
Eina_Stringshare *mime_type = _decrypt_type(edata->selection_data[selection].requested_type);
if (!x11_data->data)
EINA_SAFETY_ON_NULL_GOTO(ev->data, err);
if (eina_streq(mime_type, "text/uri-list"))
{
ERR("delivering NULL content");
return;
Ecore_X_Selection_Data_Files *files = ev->data;
Efreet_Uri *uri;
Eina_Strbuf *strbuf;
int i;
strbuf = eina_strbuf_new();
for (i = 0; i < files->num_files ; i++)
{
uri = efreet_uri_decode(files->files[i]);
if (uri)
{
eina_strbuf_append(strbuf, uri->path);
efreet_uri_free(uri);
}
else
{
eina_strbuf_append(strbuf, files->files[i]);
}
if (i < (files->num_files - 1))
eina_strbuf_append(strbuf, "\n");
}
result = _create_deliveriy_content(eina_strbuf_length_get(strbuf) + 1, eina_strbuf_string_get(strbuf), mime_type);
eina_strbuf_free(strbuf);
}
if (eina_str_has_prefix(mime_type,"text"))
else if (eina_str_has_prefix(mime_type,"text"))
{
Ecore_X_Selection_Data *x11_data = ev->data;
//ensure that we always have a \0 at the end, there is no assertion that \0 is included here.
void *null_terminated = eina_memdup(x11_data->data, x11_data->length, EINA_TRUE);
@ -3877,6 +3904,7 @@ _deliver_content(Ecore_Evas *ee, Ecore_Evas_Engine_Data_X11 *edata, Ecore_Evas_S
}
else if (eina_str_has_prefix(mime_type,"image"))
{
Ecore_X_Selection_Data *x11_data = ev->data;
Eina_Content *tmp_container = eina_content_new((Eina_Slice){.len = x11_data->length, .mem = x11_data->data}, mime_type);
const char *file = eina_content_as_file(tmp_container);
@ -3885,9 +3913,10 @@ _deliver_content(Ecore_Evas *ee, Ecore_Evas_Engine_Data_X11 *edata, Ecore_Evas_S
}
else
{
Ecore_X_Selection_Data *x11_data = ev->data;
result = _create_deliveriy_content(x11_data->length, x11_data->data, mime_type);
}
EINA_SAFETY_ON_NULL_RETURN(result);
EINA_SAFETY_ON_NULL_GOTO(result, err);
//ensure that we deliver the correct type, we might have choosen a convertion before
if (edata->selection_data[selection].later_conversion != mime_type)
@ -3901,6 +3930,12 @@ _deliver_content(Ecore_Evas *ee, Ecore_Evas_Engine_Data_X11 *edata, Ecore_Evas_S
eina_content_free(result);
_clear_selection_delivery(ee, selection);
if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
ecore_x_dnd_send_finished();
return;
err:
eina_promise_reject(edata->selection_data[selection].delivery, ecore_evas_no_selection);
if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
ecore_x_dnd_send_finished();
}
@ -4021,6 +4056,11 @@ _eina_content_converter(char *target, void *data, int size EINA_UNUSED, void **d
{
Ecore_Evas_X11_Selection_Data *sdata = data;
Eina_Bool ret = EINA_FALSE;;
if (size != sizeof(Ecore_Evas_X11_Selection_Data)) return EINA_FALSE;
if (!EINA_MAGIC_CHECK(sdata, ECORE_EVAS_X11_SELECTION)) return EINA_FALSE;
if (eina_streq(target, "TARGETS") || eina_streq(target, "ATOM"))
{
//list all available types that we have currently
@ -4154,8 +4194,9 @@ _ecore_evas_x_dnd_position(void *udata EINA_UNUSED, int type EINA_UNUSED, void *
ee = ecore_event_window_match(pos->win);
EINA_SAFETY_ON_NULL_GOTO(ee, end);
ecore_evas_geometry_get(ee, &x, &y, &w, &h);
ecore_evas_dnd_position_set(ee, 1, EINA_POSITION2D(pos->position.x - x, pos->position.y - y));
ecore_x_dnd_send_status(EINA_TRUE, EINA_FALSE, (Ecore_X_Rectangle){x,y,w,h}, pos->action);
Eina_Bool used = ecore_evas_dnd_position_set(ee, 1, EINA_POSITION2D(pos->position.x - x, pos->position.y - y));
if (used)
ecore_x_dnd_send_status(EINA_TRUE, EINA_FALSE, (Ecore_X_Rectangle){x,y,w,h}, pos->action);
end:
return ECORE_CALLBACK_PASS_ON;
}
@ -4294,6 +4335,7 @@ _ecore_evas_x_selection_window_init(Ecore_Evas *ee)
ecore_x_fixes_window_selection_notification_request(ee->prop.window, ecore_evas_selection_to_atom[i]);
edata->selection_data[i].ee = ee;
edata->selection_data[i].buffer = i;
EINA_MAGIC_SET(&edata->selection_data[i], ECORE_EVAS_X11_SELECTION);
}
ecore_x_dnd_aware_set(ee->prop.window, EINA_TRUE);
edata->init_job = ecore_job_add(_deliver_selection_changed, ee);

View File

@ -14,7 +14,7 @@ endif
shared_module(mod_full_name, engine_src,
include_directories : config_dir + [engine_include_dir],
dependencies : [eina, ecore_evas, ecore_input_evas] + engine_deps,
dependencies : [eina, ecore_evas, ecore_input_evas, efreet] + engine_deps,
install : true,
install_dir : mod_install_dir,
name_suffix : sys_mod_extension