forked from enlightenment/efl
evas: Fix dangling references with input devices
This solves issues with efl_input_dup() which didn't properly give a reference to the caller, resulting in dangling eo ids. Note: This may trigger leaks (instead of invalid refs), but this now actually reflects the meaning of @owned. This should work with bindings and C API users should know to call efl_unref(). This patch is the reason for the previous improvements on eo_debug. @fix
This commit is contained in:
parent
3dc140abfb
commit
96d94e0076
|
@ -114,7 +114,7 @@ struct _Efl_Input_Focus_Data
|
||||||
{
|
{
|
||||||
Eo *eo;
|
Eo *eo;
|
||||||
Efl_Input_Device *device; //The seat
|
Efl_Input_Device *device; //The seat
|
||||||
Eo *object; //The focused object - Efl.Canvas.Object or Efl.Canvas.
|
Eo *object_wref; // wref on the focused object - Efl.Canvas.Object or Efl.Canvas.
|
||||||
double timestamp;
|
double timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,15 @@ mixin Efl.Input.Event (Efl.Interface, Efl.Object)
|
||||||
[[Resets the internal data to 0 or default values.]]
|
[[Resets the internal data to 0 or default values.]]
|
||||||
}
|
}
|
||||||
dup @pure_virtual {
|
dup @pure_virtual {
|
||||||
[[Creates a copy of this event.]]
|
[[Creates a copy of this event.
|
||||||
return: Efl.Input.Event @owned; [[Event copy]]
|
|
||||||
|
The returned event object is similar to the given object in most
|
||||||
|
ways except that @.fake will be $true.
|
||||||
|
|
||||||
|
Note: A reference is given to the caller. In order to avoid leaks
|
||||||
|
the C API users should call $efl_unref() after use.
|
||||||
|
]]
|
||||||
|
return: Efl.Input.Event @owned; [[Event copy, marked as @.fake.]]
|
||||||
}
|
}
|
||||||
@property device @pure_virtual {
|
@property device @pure_virtual {
|
||||||
[[Input device that originated this event.]]
|
[[Input device that originated this event.]]
|
||||||
|
|
|
@ -39,6 +39,7 @@ _del_hook(Eo *evt)
|
||||||
static void
|
static void
|
||||||
_efl_input_focus_free(Efl_Input_Focus_Data *pd)
|
_efl_input_focus_free(Efl_Input_Focus_Data *pd)
|
||||||
{
|
{
|
||||||
|
efl_wref_del_safe(&pd->object_wref);
|
||||||
efl_unref(pd->device);
|
efl_unref(pd->device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,13 +72,13 @@ EOLIAN static void
|
||||||
_efl_input_focus_object_set(Eo *obj EINA_UNUSED, Efl_Input_Focus_Data *pd,
|
_efl_input_focus_object_set(Eo *obj EINA_UNUSED, Efl_Input_Focus_Data *pd,
|
||||||
Efl_Object *object)
|
Efl_Object *object)
|
||||||
{
|
{
|
||||||
pd->object = object;
|
pd->object_wref = object;
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static Efl_Object *
|
EOLIAN static Efl_Object *
|
||||||
_efl_input_focus_object_get(Eo *obj EINA_UNUSED, Efl_Input_Focus_Data *pd)
|
_efl_input_focus_object_get(Eo *obj EINA_UNUSED, Efl_Input_Focus_Data *pd)
|
||||||
{
|
{
|
||||||
return pd->object;
|
return pd->object_wref;
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static void
|
EOLIAN static void
|
||||||
|
@ -111,18 +112,20 @@ _efl_input_focus_efl_input_event_timestamp_get(Eo *obj EINA_UNUSED,
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static Efl_Input_Focus *
|
EOLIAN static Efl_Input_Focus *
|
||||||
_efl_input_focus_efl_input_event_dup(Eo *obj, Efl_Input_Focus_Data *pd)
|
_efl_input_focus_efl_input_event_dup(Eo *obj EINA_UNUSED, Efl_Input_Focus_Data *pd)
|
||||||
{
|
{
|
||||||
Efl_Input_Focus_Data *ev;
|
Efl_Input_Focus_Data *ev;
|
||||||
Efl_Input_Focus *evt;
|
Efl_Input_Focus *evt;
|
||||||
|
|
||||||
evt = efl_input_instance_get(MY_CLASS, efl_parent_get(obj), (void **) &ev);
|
evt = efl_add(MY_CLASS, NULL);
|
||||||
if (!evt || !ev) return NULL;
|
ev = efl_data_scope_get(evt, MY_CLASS);
|
||||||
|
if (!ev) return NULL;
|
||||||
|
|
||||||
|
memcpy(ev, pd, sizeof(*ev));
|
||||||
ev->eo = evt;
|
ev->eo = evt;
|
||||||
ev->object = pd->object;
|
|
||||||
ev->device = efl_ref(pd->device);
|
ev->device = efl_ref(pd->device);
|
||||||
ev->timestamp = pd->timestamp;
|
efl_wref_add(ev->object_wref, &ev->object_wref);
|
||||||
|
|
||||||
return evt;
|
return evt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,17 +101,19 @@ _efl_input_hold_efl_input_event_reset(Eo *obj, Efl_Input_Hold_Data *pd)
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static Efl_Input_Event *
|
EOLIAN static Efl_Input_Event *
|
||||||
_efl_input_hold_efl_input_event_dup(Eo *obj, Efl_Input_Hold_Data *pd)
|
_efl_input_hold_efl_input_event_dup(Eo *obj EINA_UNUSED, Efl_Input_Hold_Data *pd)
|
||||||
{
|
{
|
||||||
Efl_Input_Hold_Data *ev;
|
Efl_Input_Hold_Data *ev;
|
||||||
Efl_Input_Event *evt = efl_add(EFL_INPUT_HOLD_CLASS, efl_parent_get(obj));
|
Efl_Input_Hold *evt;
|
||||||
|
|
||||||
|
evt = efl_add(MY_CLASS, NULL);
|
||||||
ev = efl_data_scope_get(evt, MY_CLASS);
|
ev = efl_data_scope_get(evt, MY_CLASS);
|
||||||
if (!ev) return NULL;
|
if (!ev) return NULL;
|
||||||
|
|
||||||
|
memcpy(ev, pd, sizeof(*ev));
|
||||||
ev->eo = evt;
|
ev->eo = evt;
|
||||||
ev->timestamp = pd->timestamp;
|
ev->legacy = NULL;
|
||||||
ev->data = pd->data;
|
ev->evas_done = 0;
|
||||||
ev->hold = pd->hold;
|
|
||||||
ev->device = efl_ref(pd->device);
|
ev->device = efl_ref(pd->device);
|
||||||
|
|
||||||
return evt;
|
return evt;
|
||||||
|
|
|
@ -188,13 +188,14 @@ _efl_input_key_efl_input_event_reset(Eo *obj EINA_UNUSED, Efl_Input_Key_Data *pd
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static Efl_Input_Event *
|
EOLIAN static Efl_Input_Event *
|
||||||
_efl_input_key_efl_input_event_dup(Eo *obj, Efl_Input_Key_Data *pd)
|
_efl_input_key_efl_input_event_dup(Eo *obj EINA_UNUSED, Efl_Input_Key_Data *pd)
|
||||||
{
|
{
|
||||||
Efl_Input_Key_Data *ev;
|
Efl_Input_Key_Data *ev;
|
||||||
Efl_Input_Key *evt;
|
Efl_Input_Key *evt;
|
||||||
|
|
||||||
evt = efl_input_instance_get(MY_CLASS, efl_parent_get(obj), (void **) &ev);
|
evt = efl_add(MY_CLASS, NULL);
|
||||||
if (!evt || !ev) return NULL;
|
ev = efl_data_scope_get(evt, MY_CLASS);
|
||||||
|
if (!ev) return NULL;
|
||||||
|
|
||||||
memcpy(ev, pd, sizeof(*ev));
|
memcpy(ev, pd, sizeof(*ev));
|
||||||
ev->eo = evt;
|
ev->eo = evt;
|
||||||
|
|
|
@ -143,13 +143,14 @@ _efl_input_pointer_efl_input_event_reset(Eo *obj, Efl_Input_Pointer_Data *pd)
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static Efl_Input_Event *
|
EOLIAN static Efl_Input_Event *
|
||||||
_efl_input_pointer_efl_input_event_dup(Eo *obj, Efl_Input_Pointer_Data *pd)
|
_efl_input_pointer_efl_input_event_dup(Eo *obj EINA_UNUSED, Efl_Input_Pointer_Data *pd)
|
||||||
{
|
{
|
||||||
Efl_Input_Pointer_Data *ev;
|
Efl_Input_Pointer_Data *ev;
|
||||||
Efl_Input_Pointer *evt;
|
Efl_Input_Focus *evt;
|
||||||
|
|
||||||
evt = efl_input_instance_get(MY_CLASS, efl_parent_get(obj), (void **) &ev);
|
evt = efl_add(MY_CLASS, NULL);
|
||||||
if (!evt) return NULL;
|
ev = efl_data_scope_get(evt, MY_CLASS);
|
||||||
|
if (!ev) return NULL;
|
||||||
|
|
||||||
memcpy(ev, pd, sizeof(*ev));
|
memcpy(ev, pd, sizeof(*ev));
|
||||||
ev->eo = evt;
|
ev->eo = evt;
|
||||||
|
@ -157,7 +158,6 @@ _efl_input_pointer_efl_input_event_dup(Eo *obj, Efl_Input_Pointer_Data *pd)
|
||||||
ev->evas_done = 0;
|
ev->evas_done = 0;
|
||||||
ev->win_fed = 0;
|
ev->win_fed = 0;
|
||||||
ev->fake = 1;
|
ev->fake = 1;
|
||||||
ev->legacy = NULL;
|
|
||||||
ev->device = efl_ref(pd->device);
|
ev->device = efl_ref(pd->device);
|
||||||
|
|
||||||
return evt;
|
return evt;
|
||||||
|
|
|
@ -460,7 +460,7 @@ evas_device_seat_id_get(const Evas_Device *dev)
|
||||||
void
|
void
|
||||||
_evas_device_cleanup(Evas *eo_e)
|
_evas_device_cleanup(Evas *eo_e)
|
||||||
{
|
{
|
||||||
Eina_List *cpy;
|
Eina_List *cpy, *deleted = NULL;
|
||||||
Evas_Device *dev;
|
Evas_Device *dev;
|
||||||
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
|
||||||
|
|
||||||
|
@ -473,19 +473,26 @@ _evas_device_cleanup(Evas *eo_e)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the device is deleted, _del_cb will remove the device
|
/* If the device is deleted, _del_cb will remove the device
|
||||||
from the devices list. */
|
* from the devices list. Ensure we delete them only once, and only if this
|
||||||
|
* Evas is the owner, otherwise we would kill external references (eg.
|
||||||
|
* from efl_input_dup()). */
|
||||||
again:
|
again:
|
||||||
e->devices_modified = EINA_FALSE;
|
e->devices_modified = EINA_FALSE;
|
||||||
cpy = eina_list_clone(e->devices);
|
cpy = eina_list_clone(e->devices);
|
||||||
EINA_LIST_FREE(cpy, dev)
|
EINA_LIST_FREE(cpy, dev)
|
||||||
{
|
{
|
||||||
evas_device_del(dev);
|
if (!eina_list_data_find(deleted, dev) && (efl_parent_get(dev) == eo_e))
|
||||||
if (e->devices_modified)
|
|
||||||
{
|
{
|
||||||
eina_list_free(cpy);
|
evas_device_del(dev);
|
||||||
goto again;
|
deleted = eina_list_append(deleted, dev);
|
||||||
|
if (e->devices_modified)
|
||||||
|
{
|
||||||
|
eina_list_free(cpy);
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
eina_list_free(deleted);
|
||||||
|
|
||||||
/* Not all devices were deleted. The user probably will unref them later.
|
/* Not all devices were deleted. The user probably will unref them later.
|
||||||
Since Evas will be deleted, remove the del callback from them and
|
Since Evas will be deleted, remove the del callback from them and
|
||||||
|
@ -493,9 +500,7 @@ again:
|
||||||
*/
|
*/
|
||||||
EINA_LIST_FREE(e->devices, dev)
|
EINA_LIST_FREE(e->devices, dev)
|
||||||
{
|
{
|
||||||
efl_event_callback_call(e->evas,
|
efl_event_callback_call(e->evas, EFL_CANVAS_EVENT_DEVICE_REMOVED, dev);
|
||||||
EFL_CANVAS_EVENT_DEVICE_REMOVED,
|
|
||||||
dev);
|
|
||||||
efl_event_callback_del(dev, EFL_EVENT_DEL, _del_cb, e);
|
efl_event_callback_del(dev, EFL_EVENT_DEL, _del_cb, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ _evas_focus_dispatch_event(Evas_Object_Protected_Data *obj, Efl_Input_Device *se
|
||||||
if (!evt) return;
|
if (!evt) return;
|
||||||
|
|
||||||
ev_data->device = efl_ref(seat);
|
ev_data->device = efl_ref(seat);
|
||||||
ev_data->object = obj->object;
|
efl_wref_add(obj->object, &ev_data->object_wref);
|
||||||
ev_data->timestamp = time(NULL);
|
ev_data->timestamp = time(NULL);
|
||||||
|
|
||||||
if (in)
|
if (in)
|
||||||
|
|
Loading…
Reference in New Issue