discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=1beecb72d71a164abc37c2f5c8bcc6a21c8ef8a6

commit 1beecb72d71a164abc37c2f5c8bcc6a21c8ef8a6
Author: Mike Blumenkrantz <zm...@osg.samsung.com>
Date:   Tue Aug 4 18:56:18 2015 -0400

    add server-side wl dnd
    
    weston-dnd seems to work as expected
---
 src/bin/e_comp_wl.c      |  33 +++++++++++--
 src/bin/e_comp_wl.h      |   7 +--
 src/bin/e_comp_wl_data.c | 119 +++++++++++++++++++++++++++++++++++++++++++++--
 src/bin/e_comp_wl_data.h |   3 ++
 4 files changed, 151 insertions(+), 11 deletions(-)

diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index b3c6a97..82d5f48 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -164,8 +164,12 @@ _e_comp_wl_evas_cb_mouse_in(void *data, Evas *evas 
EINA_UNUSED, Evas_Object *obj
    if (!ec->comp_data->surface) return;
 
    e_comp->wl_comp_data->ptr.ec = ec;
+   if (e_comp->wl_comp_data->drag)
+     {
+        e_comp_wl_data_device_send_enter(ec);
+        return;
+     }
    if (!eina_list_count(e_comp->wl_comp_data->ptr.resources)) return;
-
    wc = wl_resource_get_client(ec->comp_data->surface);
    serial = wl_display_next_serial(e_comp->wl_comp_data->wl.disp);
    EINA_LIST_FOREACH(e_comp->wl_comp_data->ptr.resources, l, res)
@@ -202,7 +206,11 @@ _e_comp_wl_evas_cb_mouse_out(void *data, Evas *evas 
EINA_UNUSED, Evas_Object *ob
    if (e_object_is_del(E_OBJECT(ec))) return;
 
    if (!ec->comp_data->surface) return;
-
+   if (e_comp->wl_comp_data->drag)
+     {
+        e_comp_wl_data_device_send_leave(ec);
+        return;
+     }
    if (!eina_list_count(e_comp->wl_comp_data->ptr.resources)) return;
 
    wc = wl_resource_get_client(ec->comp_data->surface);
@@ -895,6 +903,16 @@ _e_comp_wl_cb_mouse_move(void *d EINA_UNUSED, int t 
EINA_UNUSED, Ecore_Event_Mou
    e_comp->wl_comp_data->ptr.x = wl_fixed_from_int(ev->x);
    e_comp->wl_comp_data->ptr.y = wl_fixed_from_int(ev->y);
    e_screensaver_notidle();
+   if (e_comp->wl_comp_data->selection.target)
+     {
+        struct wl_resource *res;
+        int x, y;
+
+        res = 
e_comp_wl_data_find_for_client(wl_resource_get_client(e_comp->wl_comp_data->selection.target->comp_data->surface));
+        x = ev->x - e_comp->wl_comp_data->selection.target->client.x;
+        y = ev->y - e_comp->wl_comp_data->selection.target->client.y;
+        wl_data_device_send_motion(res, ev->timestamp, wl_fixed_from_int(x), 
wl_fixed_from_int(y));
+     }
    return ECORE_CALLBACK_RENEW;
 }
 
@@ -1088,7 +1106,16 @@ _e_comp_wl_surface_state_commit(E_Client *ec, 
E_Comp_Wl_Surface_State *state)
                   ecore_evas_pointer_xy_get(e_comp->ee, &ec->mouse.current.mx, 
&ec->mouse.current.my);
                   ec->netwm.sync.send_time = ecore_loop_time_get();
                }
-             e_client_util_move_resize_without_frame(ec, x, y, state->bw, 
state->bh);
+             if (e_comp->wl_comp_data->drag_client && 
(e_comp->wl_comp_data->drag_client == ec))
+               {
+                  e_comp->wl_comp_data->drag->dx -= state->sx;
+                  e_comp->wl_comp_data->drag->dy -= state->sy;
+                  e_drag_move(e_comp->wl_comp_data->drag,
+                    e_comp->wl_comp_data->drag->x + state->sx, 
e_comp->wl_comp_data->drag->y + state->sy);
+                  e_drag_resize(e_comp->wl_comp_data->drag, state->bw, 
state->bh);
+               }
+             else
+               e_client_util_move_resize_without_frame(ec, x, y, state->bw, 
state->bh);
           }
 
         if (ec->new_client)
diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h
index 67cb677..771389d 100644
--- a/src/bin/e_comp_wl.h
+++ b/src/bin/e_comp_wl.h
@@ -192,6 +192,7 @@ struct _E_Comp_Wl_Data
         uint32_t serial;
         struct wl_signal signal;
         struct wl_listener data_source_listener;
+        E_Client *target;
      } selection;
 
    struct
@@ -231,9 +232,9 @@ struct _E_Comp_Wl_Data
    struct wl_client *xwl_client;
    Eina_List *xwl_pending;
 
-   /* Eina_List *retry_clients; */
-   /* Ecore_Timer *retry_timer; */
-   Eina_Bool restack : 1;
+   E_Drag *drag;
+   E_Client *drag_client;
+   void *drag_source;
 };
 
 struct _E_Comp_Wl_Client_Data
diff --git a/src/bin/e_comp_wl_data.c b/src/bin/e_comp_wl_data.c
index 8579d0f..f1843df 100644
--- a/src/bin/e_comp_wl_data.c
+++ b/src/bin/e_comp_wl_data.c
@@ -1,3 +1,4 @@
+#define EXECUTIVE_MODE_ENABLED
 #define E_COMP_WL
 #include "e.h"
 
@@ -268,25 +269,67 @@ _e_comp_wl_data_device_selection_set(void *data 
EINA_UNUSED, E_Comp_Wl_Data_Sour
 }
 
 static void
+_e_comp_wl_data_device_drag_finished(E_Drag *drag, int dropped)
+{
+   Evas_Object *o;
+
+   o = edje_object_part_swallow_get(drag->comp_object, "e.swallow.content");
+   if (eina_streq(evas_object_type_get(o), "e_comp_object"))
+     edje_object_part_unswallow(drag->comp_object, o);
+   else
+     e_zoomap_child_set(o, NULL);
+   evas_object_hide(o);
+   evas_object_pass_events_set(o, 1);
+   if (e_comp->wl_comp_data->drag != drag) return;
+   if (e_comp->wl_comp_data->selection.target && (!dropped))
+     {
+        struct wl_resource *res;
+
+        res = 
e_comp_wl_data_find_for_client(wl_resource_get_client(e_comp->wl_comp_data->selection.target->comp_data->surface));
+        if (res)
+          {
+             wl_data_device_send_drop(res);
+             wl_data_device_send_leave(res);
+          }
+     }
+   e_comp->wl_comp_data->drag = NULL;
+   e_comp->wl_comp_data->drag_client = NULL;
+   e_comp->wl_comp_data->selection.target = NULL;
+   e_comp->wl_comp_data->drag_source = NULL;
+}
+
+static void
 _e_comp_wl_data_device_cb_drag_start(struct wl_client *client, struct 
wl_resource *resource EINA_UNUSED, struct wl_resource *source_resource, struct 
wl_resource *origin_resource, struct wl_resource *icon_resource, uint32_t 
serial)
 {
    E_Comp_Wl_Data_Source *source;
    Eina_List *l;
    struct wl_resource *res;
+   E_Client *ec = NULL;
+   int x, y;
 
    DBG("Data Device Drag Start");
 
    if ((e_comp->wl_comp_data->kbd.focus) && (e_comp->wl_comp_data->kbd.focus 
!= origin_resource)) return;
 
    if (!(source = wl_resource_get_user_data(source_resource))) return;
+   e_comp->wl_comp_data->drag_source = source;
 
-   /* TODO: create icon for pointer ?? */
    if (icon_resource)
      {
-        E_Pixmap *cp;
-
         DBG("\tHave Icon Resource: %p", icon_resource);
-        cp = wl_resource_get_user_data(icon_resource);
+        ec = wl_resource_get_user_data(icon_resource);
+        if (!ec->re_manage)
+          {
+             ec->re_manage = 1;
+
+             ec->lock_focus_out = ec->override = 1;
+             ec->icccm.title = eina_stringshare_add("noshadow");
+             ec->layer = E_LAYER_CLIENT_DRAG;
+             evas_object_layer_set(ec->frame, E_LAYER_CLIENT_DRAG);
+             
e_client_focus_stack_set(eina_list_remove(e_client_focus_stack_get(), ec));
+             EC_CHANGED(ec);
+             e_comp->wl_comp_data->drag_client = ec;
+          }
      }
 
    EINA_LIST_FOREACH(e_comp->wl_comp_data->ptr.resources, l, res)
@@ -296,7 +339,14 @@ _e_comp_wl_data_device_cb_drag_start(struct wl_client 
*client, struct wl_resourc
         wl_pointer_send_leave(res, serial, e_comp->wl_comp_data->kbd.focus);
      }
 
-   /* TODO: pointer start drag */
+   evas_pointer_canvas_xy_get(e_comp->evas, &x, &y);
+   e_comp->wl_comp_data->drag = e_drag_new(x, y,
+                                           NULL, 0, NULL, 0, NULL, 
_e_comp_wl_data_device_drag_finished);
+   if (ec)
+     e_drag_object_set(e_comp->wl_comp_data->drag, ec->frame);
+   e_drag_start(e_comp->wl_comp_data->drag, x, y);
+   if (e_comp->wl_comp_data->ptr.ec)
+     e_comp_wl_data_device_send_enter(e_comp->wl_comp_data->ptr.ec);
 }
 
 static void
@@ -642,6 +692,65 @@ _e_comp_wl_clipboard_create(void)
    wl_signal_add(&e_comp->wl_comp_data->selection.signal, 
&e_comp->wl_comp_data->clipboard.listener);
 }
 
+static void
+_e_comp_wl_data_device_target_del(void *data, Evas *e EINA_UNUSED, Evas_Object 
*obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   E_Client *ec = data;
+
+   if (e_comp->wl_comp_data->selection.target == ec)
+     e_comp->wl_comp_data->selection.target = NULL;
+}
+
+EINTERN void
+e_comp_wl_data_device_send_enter(E_Client *ec)
+{
+   struct wl_resource *data_device_res, *offer_res;
+   uint32_t serial;
+   int x, y;
+
+   data_device_res =
+      
e_comp_wl_data_find_for_client(wl_resource_get_client(ec->comp_data->surface));
+   if (!data_device_res) return;
+
+   offer_res = e_comp_wl_data_device_send_offer(ec);
+   if (e_comp->wl_comp_data->selection.data_source && (!offer_res)) return;
+   e_comp->wl_comp_data->selection.target = ec;
+   evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_DEL, 
_e_comp_wl_data_device_target_del, ec);
+
+   x = wl_fixed_to_int(e_comp->wl_comp_data->ptr.x) - 
e_comp->wl_comp_data->selection.target->client.x;
+   y = wl_fixed_to_int(e_comp->wl_comp_data->ptr.y) - 
e_comp->wl_comp_data->selection.target->client.y;
+   serial = wl_display_next_serial(e_comp->wl_comp_data->wl.disp);
+   wl_data_device_send_enter(data_device_res, serial, ec->comp_data->surface,
+                             wl_fixed_from_int(x), wl_fixed_from_int(y), 
offer_res);
+}
+
+EINTERN void
+e_comp_wl_data_device_send_leave(E_Client *ec)
+{
+   struct wl_resource *res;
+
+   evas_object_event_callback_del_full(ec->frame, EVAS_CALLBACK_DEL, 
_e_comp_wl_data_device_target_del, ec);
+   if (e_comp->wl_comp_data->selection.target == ec)
+     e_comp->wl_comp_data->selection.target = NULL;
+   res = 
e_comp_wl_data_find_for_client(wl_resource_get_client(ec->comp_data->surface));
+   wl_data_device_send_leave(res);
+}
+
+EINTERN void *
+e_comp_wl_data_device_send_offer(E_Client *ec)
+{
+   struct wl_resource *data_device_res, *offer_res = NULL;
+   E_Comp_Wl_Data_Source *source;
+
+   data_device_res =
+      
e_comp_wl_data_find_for_client(wl_resource_get_client(ec->comp_data->surface));
+   if (!data_device_res) return NULL;
+   source = e_comp->wl_comp_data->drag_source;
+   if (source)
+     offer_res = _e_comp_wl_data_device_data_offer_create(source, 
data_device_res);
+   return offer_res;
+}
+
 EINTERN void
 e_comp_wl_data_device_keyboard_focus_set(void)
 {
diff --git a/src/bin/e_comp_wl_data.h b/src/bin/e_comp_wl_data.h
index 69a9efc..5fc56c2 100644
--- a/src/bin/e_comp_wl_data.h
+++ b/src/bin/e_comp_wl_data.h
@@ -50,6 +50,9 @@ struct _E_Comp_Wl_Clipboard_Offer
    size_t offset;
 };
 
+EINTERN void e_comp_wl_data_device_send_enter(E_Client *ec);
+EINTERN void e_comp_wl_data_device_send_leave(E_Client *ec);
+EINTERN void *e_comp_wl_data_device_send_offer(E_Client *ec);
 EINTERN void e_comp_wl_data_device_keyboard_focus_set(void);
 EINTERN Eina_Bool e_comp_wl_data_manager_init(void);
 EINTERN void e_comp_wl_data_manager_shutdown(void);

-- 


Reply via email to