this took waaaaayyyyyyyyyyyyyy longer than I expected, but we now have support for XDS in efm, which will allow you to drag things from many other applications TO efm windows (eg. dragging a file from an archive in file-roller to an efm window will now extract the dragged file to the location of the window)

SVN revision: 76465
This commit is contained in:
Mike Blumenkrantz 2012-09-11 16:17:24 +00:00
parent 414db11d31
commit 20f84d3cee
3 changed files with 103 additions and 10 deletions

View File

@ -61,8 +61,11 @@ static Eina_List *_drag_list = NULL;
static E_Drag *_drag_current = NULL;
static XDnd *_xdnd = NULL;
#define XDS_ATOM "XdndDirectSave0"
static Ecore_X_Atom _xds_atom = 0;
static Ecore_X_Atom _text_atom = 0;
static const char *_type_text_uri_list = NULL;
static const char *_type_xds = NULL;
static const char *_type_text_x_moz_url = NULL;
static const char *_type_enlightenment_x_file = NULL;
@ -75,8 +78,11 @@ EINTERN int
e_dnd_init(void)
{
_type_text_uri_list = eina_stringshare_add("text/uri-list");
_type_xds = eina_stringshare_add(XDS_ATOM);
_type_text_x_moz_url = eina_stringshare_add("text/x-moz-url");
_type_enlightenment_x_file = eina_stringshare_add("enlightenment/x-file");
_xds_atom = ecore_x_atom_get(XDS_ATOM);
_text_atom = ecore_x_atom_get("text/plain");
_drop_win_hash = eina_hash_string_superfast_new(NULL);
_drop_handlers_responsives = eina_hash_string_superfast_new(NULL);
@ -137,11 +143,14 @@ e_dnd_shutdown(void)
eina_hash_free(_drop_handlers_responsives);
eina_stringshare_del(_type_text_uri_list);
eina_stringshare_del(_type_xds);
eina_stringshare_del(_type_text_x_moz_url);
eina_stringshare_del(_type_enlightenment_x_file);
_type_text_uri_list = NULL;
_type_xds = NULL;
_type_text_x_moz_url = NULL;
_type_enlightenment_x_file = NULL;
_text_atom = _xds_atom = 0;
return 1;
}
@ -348,6 +357,44 @@ e_drag_xdnd_start(E_Drag *drag, int x, int y)
return 1;
}
EAPI void
e_drop_handler_xds_set(E_Drop_Handler *handler, Ecore_Task_Cb cb)
{
handler->cb.xds = cb;
}
/* should only be used for windows */
EAPI void
e_drop_xds_update(Eina_Bool enable, const char *value)
{
Ecore_X_Window xwin;
char buf[PATH_MAX + 8];
char *file;
int size;
size_t len;
enable = !!enable;
xwin = ecore_x_selection_owner_get(ECORE_X_ATOM_SELECTION_XDND);
if (enable)
{
if (!ecore_x_window_prop_property_get(xwin, _xds_atom, _text_atom, 8, (unsigned char **)&file, &size))
return;
len = strlen(value);
if (size + len + 8 + 1 > sizeof(buf))
{
free(file);
return;
}
snprintf(buf, sizeof(buf), "file://%s/", value);
strncat(buf, file, size);
free(file);
ecore_x_window_prop_property_set(xwin, _xds_atom, _text_atom, 8, (void*)buf, size + len + 8);
}
else
ecore_x_window_prop_property_del(xwin, _xds_atom);
}
EAPI E_Drop_Handler *
e_drop_handler_add(E_Object *obj,
void *data,
@ -1360,7 +1407,19 @@ _e_dnd_cb_event_dnd_drop(void *data __UNUSED__, int type __UNUSED__, void *event
if (_xdnd)
{
ecore_x_selection_xdnd_request(ev->win, _xdnd->type);
E_Drop_Handler *h;
Eina_Bool req = EINA_TRUE;
Eina_List *l;
EINA_LIST_FOREACH(_drop_handlers, l, h)
{
if (!h->active) continue;
if (_e_drag_win_matches(h, ev->win, 1) && h->entered && h->cb.xds)
{
req = h->cb.xds(h->cb.data);
}
}
if (req) ecore_x_selection_xdnd_request(ev->win, _xdnd->type);
_xdnd->x = ev->position.x;
_xdnd->y = ev->position.y;

View File

@ -67,6 +67,7 @@ struct _E_Drop_Handler
void (*move)(void *data, const char *type, void *event);
void (*leave)(void *data, const char *type, void *event);
void (*drop)(void *data, const char *type, void *event);
Ecore_Task_Cb xds;
void *data;
} cb;
@ -127,6 +128,8 @@ EAPI void e_drag_key_up_cb_set(E_Drag *drag, void (*func)(E_Drag *dra
EAPI int e_drag_start(E_Drag *drag, int x, int y);
EAPI int e_drag_xdnd_start(E_Drag *drag, int x, int y);
EAPI void e_drop_xds_update(Eina_Bool enable, const char *value);
EAPI void e_drop_handler_xds_set(E_Drop_Handler *handler, Ecore_Task_Cb cb);
EAPI E_Drop_Handler *e_drop_handler_add(E_Object *obj,
void *data,
void (*enter_cb)(void *data, const char *type, void *event),

View File

@ -483,6 +483,14 @@ static const char *_e_fm2_mime_inode_directory = NULL;
static const char *_e_fm2_mime_app_desktop = NULL;
static const char *_e_fm2_mime_app_edje = NULL;
static const char *_e_fm2_mime_text_uri_list = NULL;
static const char *_e_fm2_xds = NULL;
static const char **_e_fm2_dnd_types[] =
{
&_e_fm2_mime_text_uri_list,
&_e_fm2_xds,
NULL
};
static Ecore_Timer *_e_fm2_mime_flush = NULL;
static Ecore_Timer *_e_fm2_mime_clear = NULL;
@ -787,6 +795,7 @@ e_fm2_init(void)
_e_fm2_mime_app_desktop = eina_stringshare_add("application/x-desktop");
_e_fm2_mime_app_edje = eina_stringshare_add("application/x-extension-edj");
_e_fm2_mime_text_uri_list = eina_stringshare_add("text/uri-list");
_e_fm2_xds = eina_stringshare_add("XdndDirectSave0");
_e_fm2_favorites_thread = ecore_thread_run(_e_fm2_favorites_thread_cb,
_e_fm2_thread_cleanup_cb,
@ -819,6 +828,7 @@ e_fm2_shutdown(void)
eina_stringshare_replace(&_e_fm2_mime_app_desktop, NULL);
eina_stringshare_replace(&_e_fm2_mime_app_edje, NULL);
eina_stringshare_replace(&_e_fm2_mime_text_uri_list, NULL);
eina_stringshare_replace(&_e_fm2_xds, NULL);
/// DBG
if (_e_fm2_op_registry_entry_add_handler)
@ -864,6 +874,16 @@ e_fm2_add(Evas *evas)
return evas_object_smart_add(evas, _e_fm2_smart);
}
static Eina_Bool
_e_fm2_dir_xds_update(E_Fm2_Smart_Data *sd)
{
Eina_Bool allow;
allow = (sd->realpath && ecore_file_can_write(sd->realpath));
e_drop_xds_update(allow, sd->realpath);
return allow;
}
static void
_e_fm2_cb_mount_ok(void *data)
{
@ -1523,7 +1543,7 @@ e_fm2_view_flags_get(Evas_Object *obj)
EAPI void
e_fm2_window_object_set(Evas_Object *obj, E_Object *eobj)
{
const char *drop[] = { "enlightenment/desktop", "enlightenment/border", "text/uri-list" };
const char *drop[] = { "enlightenment/desktop", "enlightenment/border", "text/uri-list", "XdndDirectSave0"};
EFM_SMART_CHECK();
sd->eobj = eobj;
@ -1534,9 +1554,10 @@ e_fm2_window_object_set(Evas_Object *obj, E_Object *eobj)
_e_fm2_cb_dnd_move,
_e_fm2_cb_dnd_leave,
_e_fm2_cb_dnd_drop,
drop, 3,
drop, 4,
sd->x, sd->y, sd->w, sd->h);
e_drop_handler_responsive_set(sd->drop_handler);
e_drop_handler_xds_set(sd->drop_handler, (Ecore_Task_Cb)_e_fm2_dir_xds_update);
}
EAPI void
@ -6016,6 +6037,16 @@ _e_fm2_dnd_drop_hide(Evas_Object *obj)
}
/* FIXME: prototype + reposition + implement */
static Eina_Bool
_e_fm2_dnd_type_implemented(const char *type)
{
const char **t;
for (t = *_e_fm2_dnd_types; t; t++)
if (type == *t) return EINA_TRUE;
return EINA_FALSE;
}
static void
_e_fm2_dnd_finish(Evas_Object *obj, int refresh)
{
@ -6042,7 +6073,7 @@ _e_fm2_cb_dnd_enter(void *data __UNUSED__, const char *type, void *event)
{
E_Event_Dnd_Enter *ev;
if (type != _e_fm2_mime_text_uri_list) return;
if (!_e_fm2_dnd_type_implemented(type)) return;
ev = (E_Event_Dnd_Enter *)event;
e_drop_handler_action_set(ev->action);
}
@ -6057,7 +6088,7 @@ _e_fm2_cb_dnd_move(void *data, const char *type, void *event)
int dx, dy;
sd = data;
if (type != _e_fm2_mime_text_uri_list) return;
if (!_e_fm2_dnd_type_implemented(type)) return;
ev = (E_Event_Dnd_Move *)event;
dx = ev->x - sd->x;
dy = ev->y - sd->y;
@ -6160,7 +6191,7 @@ _e_fm2_cb_dnd_leave(void *data, const char *type, void *event __UNUSED__)
E_Fm2_Smart_Data *sd;
sd = data;
if (type != _e_fm2_mime_text_uri_list) return;
if (!_e_fm2_dnd_type_implemented(type)) return;
_e_fm2_dnd_drop_hide(sd->obj);
_e_fm2_dnd_drop_all_hide(sd->obj);
}
@ -6330,7 +6361,7 @@ _e_fm2_cb_dnd_drop(void *data, const char *type, void *event)
E_Event_Dnd_Drop *ev;
E_Fm2_Icon *ic;
Eina_List *fsel, *l, *ll, *il, *isel;
char buf[4096];
char buf[PATH_MAX];
const char *fp;
Evas_Object *obj;
Evas_Coord ox, oy, x, y;
@ -6342,8 +6373,8 @@ _e_fm2_cb_dnd_drop(void *data, const char *type, void *event)
Eina_Bool memerr = EINA_FALSE;
sd = data;
if (type != _e_fm2_mime_text_uri_list) return;
ev = (E_Event_Dnd_Drop *)event;
ev = event;
if (!_e_fm2_dnd_type_implemented(type)) return;
fsel = _e_fm2_uri_path_list_get(ev->data);
fp = eina_list_data_get(fsel);