From: Daniel Zaoui Date: Wed, 25 Feb 2015 08:36:18 +0000 (+0200) Subject: DnD/Wl: support multi-layer Drag and Drop X-Git-Tag: v1.14.0-alpha1~154 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3e928641aec401dd6d6bc1aeec082cf991bf769f;p=platform%2Fupstream%2Felementary.git DnD/Wl: support multi-layer Drag and Drop Now, we use the same way as in X11 to determine which dropable target should receive the drop data. @feature --- diff --git a/src/lib/elm_cnp.c b/src/lib/elm_cnp.c index f04e11c..08fe144 100644 --- a/src/lib/elm_cnp.c +++ b/src/lib/elm_cnp.c @@ -1292,20 +1292,28 @@ static void _dropable_coords_adjust(Dropable *dropable, Evas_Coord *x, Evas_Coord *y) { Ecore_Evas *ee; + Evas *evas = evas_object_evas_get(dropable->obj); int ex = 0, ey = 0, ew = 0, eh = 0; Evas_Object *win; - Evas_Coord x2, y2; - ee = ecore_evas_ecore_evas_get(evas_object_evas_get(dropable->obj)); + ee = ecore_evas_ecore_evas_get(evas); ecore_evas_geometry_get(ee, &ex, &ey, &ew, &eh); *x = *x - ex; *y = *y - ey; + /* For Wayland, frame coords have to be subtracted. */ + Evas_Coord fx, fy; + evas_output_framespace_get(evas, &fx, &fy, NULL, NULL); + if (fx || fy) cnp_debug("evas frame fx %d fy %d\n", fx, fy); + *x = *x - fx; + *y = *y - fy; + if (elm_widget_is(dropable->obj)) { win = elm_widget_top_get(dropable->obj); if (win && !strcmp(evas_object_type_get(win), "elm_win")) { + Evas_Coord x2, y2; int rot = elm_win_rotation_get(win); switch (rot) { @@ -2452,6 +2460,7 @@ static void _wl_dropable_handle(Dropable *drop, Evas_Coord x, Evas_Coord y, Eina static void _wl_dropable_all_set(unsigned int win, Evas_Coord x, Evas_Coord y, Eina_Bool set); static Eina_Bool _wl_drops_accept(const char *type); static unsigned int _wl_elm_widget_window_get(Evas_Object *obj); +static Evas * _wl_evas_get_from_win(unsigned int win); static void _wl_sel_obj_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) @@ -3090,6 +3099,8 @@ _wl_dnd_position(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) ev = event; + cnp_debug("mouse pos %i %i\n", ev->position.x, ev->position.y); + dragwin_x_end = ev->position.x - _dragx; dragwin_y_end = ev->position.y - _dragy; @@ -3097,51 +3108,97 @@ _wl_dnd_position(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) if (drop) { - Ecore_Evas *ee; - Evas_Coord ex = 0, ey = 0; Evas_Coord x = 0, y = 0; x = ev->position.x; y = ev->position.y; - ee = ecore_evas_ecore_evas_get(evas_object_evas_get(drop->obj)); - ecore_evas_geometry_get(ee, &ex, &ey, NULL, NULL); - x -= ex; - y -= ey; + _dropable_coords_adjust(drop, &x, &y); + Evas *evas = _wl_evas_get_from_win(ev->win); - if ((drop = _wl_dropable_find_geom(ev->win, x, y))) - { - Evas_Coord ox = 0, oy = 0; - int i = 0; - - evas_object_geometry_get(drop->obj, &ox, &oy, NULL, NULL); + Eina_List *dropable_list = evas ? _dropable_list_geom_find(evas, x, y) : NULL; - _wl_dropable_handle(drop, x - ox, y - oy, EINA_TRUE); + /* check if there is dropable (obj) can accept this drop */ + if (dropable_list) + { + Eina_List *l; + Eina_Bool found = EINA_FALSE; + Dropable *dropable = NULL; - for (i = 0; i < savedtypes.ntypes; i++) + EINA_LIST_FOREACH(dropable_list, l, dropable) { +#if 0 +FIXME: add types support + int i, j; + Eina_Inlist *itr; Dropable_Cbs *cbs; - EINA_INLIST_FOREACH(drop->cbs_list, cbs) + EINA_INLIST_FOREACH_SAFE(dropable->cbs_list, itr, cbs) + { + const char *types[CNP_N_ATOMS]; + int types_no = _x11_dnd_types_get(cbs->types, types); + for (j = 0; j < types_no; j++) + { + for (i = 0; i < savedtypes.ntypes; i++) + { + if (!strcmp(types[j], savedtypes.types[i])) + { + found = EINA_TRUE; + dropable->last.type = savedtypes.types[i]; + dropable->last.format = cbs->types; + break; + } + } + if (found) break; + } + if (found) break; + } +#else + found = EINA_TRUE; +#endif + if (found) break; + } + if (found) + { + Evas_Coord ox = 0, oy = 0; + int i = 0; + + evas_object_geometry_get(dropable->obj, &ox, &oy, NULL, NULL); + + cnp_debug("Candidate on %i %i: %p\n", x - ox, y - oy, dropable); + _wl_dropable_handle(dropable, x - ox, y - oy, EINA_TRUE); + // CCCCCCC: call dnd exit on last obj if obj != last + // CCCCCCC: call drop position on obj + + for (i = 0; i < savedtypes.ntypes; i++) { - switch (cbs->types) + Dropable_Cbs *cbs; + EINA_INLIST_FOREACH(drop->cbs_list, cbs) { - case ELM_SEL_FORMAT_TARGETS: - case ELM_SEL_FORMAT_IMAGE: - if ((!strncmp(savedtypes.types[i], "text/uri", 8)) || - (!strncmp(savedtypes.types[i], "image/", 6))) - { - wl_cnp_selection.requestwidget = drop->obj; - will_accept = EINA_TRUE; - } - break; - default: - break; + switch (cbs->types) + { + case ELM_SEL_FORMAT_TARGETS: + case ELM_SEL_FORMAT_IMAGE: + if ((!strncmp(savedtypes.types[i], "text/uri", 8)) || + (!strncmp(savedtypes.types[i], "image/", 6))) + { + wl_cnp_selection.requestwidget = drop->obj; + will_accept = EINA_TRUE; + } + break; + default: + break; + } } + if (will_accept) break; } - if (will_accept) break; + } + else + { + //if not: send false status + cnp_debug("dnd position (%d, %d) not in obj\n", x, y); + _wl_dropable_handle(dropable_old, 0, 0, EINA_FALSE); + // CCCCCCC: call dnd exit on last obj } } - else - _wl_dropable_handle(dropable_old, 0, 0, EINA_FALSE); _wl_dropable_all_set(ev->win, x, y, EINA_TRUE); } @@ -3159,8 +3216,6 @@ _wl_dnd_drop(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { Ecore_Wl_Event_Dnd_Drop *ev; Dropable *drop; - Ecore_Evas *ee; - Evas_Coord ex = 0, ey = 0; int i = 0; ev = event; @@ -3170,13 +3225,27 @@ _wl_dnd_drop(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) savedtypes.x = ev->position.x; savedtypes.y = ev->position.y; - ee = ecore_evas_ecore_evas_get(evas_object_evas_get(drop->obj)); - ecore_evas_geometry_get(ee, &ex, &ey, NULL, NULL); - savedtypes.x -= ex; - savedtypes.y -= ey; + _dropable_coords_adjust(drop, &savedtypes.x, &savedtypes.y); + Evas *evas = _wl_evas_get_from_win(ev->win); - if (!(drop = _wl_dropable_find_geom(ev->win, savedtypes.x, savedtypes.y))) - return ECORE_CALLBACK_PASS_ON; + Eina_List *dropable_list = evas ? _dropable_list_geom_find(evas, savedtypes.x, savedtypes.y) : NULL; + + /* check if there is dropable (obj) can accept this drop */ + if (dropable_list) + { + Eina_List *l; + Eina_Bool found = EINA_FALSE; + + EINA_LIST_FOREACH(dropable_list, l, drop) + { + if (drop->last.in) + { + found = EINA_TRUE; + break; + } + } + if (!found) return ECORE_CALLBACK_PASS_ON; + } for (i = 0; i < savedtypes.ntypes; i++) { @@ -3295,13 +3364,13 @@ static void _wl_dropable_data_handle(Wl_Cnp_Selection *sel, char *data) { Dropable *drop; - unsigned int win = 0; Elm_Selection_Data sdata; int len = 0; char *s = NULL; - win = _wl_elm_widget_window_get(sel->requestwidget); - drop = _wl_dropable_find_geom(win, savedtypes.x, savedtypes.y); + Evas *evas = evas_object_evas_get(sel->requestwidget); + Eina_List *dropable_list = evas ? _dropable_list_geom_find(evas, savedtypes.x, savedtypes.y) : NULL, *l; + Eina_Bool drop_found = EINA_FALSE; len = strlen(data); if (!(s = malloc(len + 1))) return; @@ -3320,25 +3389,31 @@ _wl_dropable_data_handle(Wl_Cnp_Selection *sel, char *data) if (!savedtypes.imgfile) return; - Dropable_Cbs *cbs; - Eina_Inlist *itr; - EINA_INLIST_FOREACH_SAFE(drop->cbs_list, itr, cbs) + EINA_LIST_FOREACH(dropable_list, l, drop) { - /* If it's markup that also supports images */ - if ((cbs->types & ELM_SEL_FORMAT_MARKUP) && - (cbs->types & ELM_SEL_FORMAT_IMAGE)) - { - sdata.format = ELM_SEL_FORMAT_MARKUP; - sdata.data = (char *)savedtypes.imgfile; - if (cbs->dropcb) cbs->dropcb(cbs->dropdata, drop->obj, &sdata); - ecore_wl_dnd_drag_end(ecore_wl_input_get()); - } - else if (cbs->types & ELM_SEL_FORMAT_IMAGE) + Eina_Inlist *itr; + Dropable_Cbs *cbs; + if (drop_found) continue; + EINA_INLIST_FOREACH_SAFE(drop->cbs_list, itr, cbs) { - sdata.format = ELM_SEL_FORMAT_IMAGE; - sdata.data = (char *)savedtypes.imgfile; - if (cbs->dropcb) cbs->dropcb(cbs->dropdata, drop->obj, &sdata); - ecore_wl_dnd_drag_end(ecore_wl_input_get()); + /* If it's markup that also supports images */ + if ((cbs->types & ELM_SEL_FORMAT_MARKUP) && + (cbs->types & ELM_SEL_FORMAT_IMAGE)) + { + sdata.format = ELM_SEL_FORMAT_MARKUP; + sdata.data = (char *)savedtypes.imgfile; + if (cbs->dropcb) cbs->dropcb(cbs->dropdata, drop->obj, &sdata); + ecore_wl_dnd_drag_end(ecore_wl_input_get()); + drop_found = EINA_TRUE; + } + else if (cbs->types & ELM_SEL_FORMAT_IMAGE) + { + sdata.format = ELM_SEL_FORMAT_IMAGE; + sdata.data = (char *)savedtypes.imgfile; + if (cbs->dropcb) cbs->dropcb(cbs->dropdata, drop->obj, &sdata); + ecore_wl_dnd_drag_end(ecore_wl_input_get()); + drop_found = EINA_TRUE; + } } } ELM_SAFE_FREE(savedtypes.imgfile, free); @@ -3357,6 +3432,13 @@ _wl_dropable_find(unsigned int win) return NULL; } +static Evas * +_wl_evas_get_from_win(unsigned int win) +{ + Dropable *dropable = _wl_dropable_find(win); + return dropable ? evas_object_evas_get(dropable->obj) : NULL; +} + static Dropable * _wl_dropable_find_geom(unsigned int win, Evas_Coord x, Evas_Coord y) {