Add ecore_x_dnd_self_begin() and ecore_x_dnd_self_drop() to allow dnd
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>
Thu, 21 Feb 2013 07:49:10 +0000 (16:49 +0900)
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>
Thu, 21 Feb 2013 07:49:10 +0000 (16:49 +0900)
to your own window (drop where u drag from). helpful for elm where dnd
src/dst are object based, so we talk dnd protocol to ourselves.

ChangeLog
NEWS
src/lib/ecore_x/Ecore_X.h
src/lib/ecore_x/xcb/ecore_xcb_dnd.c
src/lib/ecore_x/xlib/ecore_x_dnd.c

index f693ee6..1ae0ace 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,12 @@
+2013-02-21  Carsten Haitzler (The Rasterman)
+
+        * Add ecore_x_dnd_self_begin() and ecore_x_dnd_self_drop() to
+        allow xdnd chatting to yourself (your source drag window).
+
 2013-02-20  Carsten Haitzler (The Rasterman)
 
         * Fix ecore-x edid fetch to ftech 128, not 100 bytes.
-        
+
 2013-02-20  Cedric Bail
 
        * Properly report file not found in Edje.
diff --git a/NEWS b/NEWS
index b0d3123..67913fb 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -30,6 +30,8 @@ Additions:
        ecore_x_e_window_profile_change_done_send()
        ecore_x_randr_crtc_info_get()
        ecore_x_randr_crtc_info_free()
+       ecore_x_dnd_self_begin()
+       ecore_x_dnd_self_drop()
     * ecore_wayland:
      - Store global wayland interfaces in a globals list so wayland programs
        can bind to other non-standard wayland protocol extensions.
index 464432d..64f2427 100644 (file)
@@ -1351,6 +1351,8 @@ EAPI void                      ecore_x_dnd_types_set(Ecore_X_Window win, const c
 EAPI void                      ecore_x_dnd_actions_set(Ecore_X_Window win, Ecore_X_Atom *actions, unsigned int num_actions);
 EAPI Eina_Bool                 ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size);
 EAPI Eina_Bool                 ecore_x_dnd_drop(void);
+EAPI Eina_Bool                 ecore_x_dnd_self_begin(Ecore_X_Window source, unsigned char *data, int size); /**< @since 1.8 */
+EAPI Eina_Bool                 ecore_x_dnd_self_drop(void); /**< @since 1.8 */
 EAPI void                      ecore_x_dnd_send_status(Eina_Bool will_accept, Eina_Bool suppress, Ecore_X_Rectangle rectangle, Ecore_X_Atom action);
 EAPI void                      ecore_x_dnd_send_finished(void);
 EAPI void                      ecore_x_dnd_source_action_set(Ecore_X_Atom action);
index 80ae6b4..543f43c 100644 (file)
@@ -132,60 +132,6 @@ ecore_x_dnd_send_status(Eina_Bool         will_accept,
 //   ecore_x_flush();
 }
 
-EAPI Eina_Bool
-ecore_x_dnd_drop(void)
-{
-   xcb_client_message_event_t ev;
-   Eina_Bool status = EINA_FALSE;
-
-   LOGFN(__FILE__, __LINE__, __FUNCTION__);
-   CHECK_XCB_CONN;
-
-   memset(&ev, 0, sizeof(xcb_client_message_event_t));
-
-   if (_source->dest)
-     {
-        ev.response_type = XCB_CLIENT_MESSAGE;
-        ev.format = 32;
-        ev.window = _source->dest;
-
-        if (_source->will_accept)
-          {
-             ev.type = ECORE_X_ATOM_XDND_DROP;
-             ev.data.data32[0] = _source->win;
-             ev.data.data32[1] = 0;
-             ev.data.data32[2] = _source->time;
-
-             xcb_send_event(_ecore_xcb_conn, 0, _source->dest,
-                            XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
-//             ecore_x_flush();
-             _source->state = ECORE_X_DND_SOURCE_DROPPED;
-             status = EINA_TRUE;
-          }
-        else
-          {
-             ev.type = ECORE_X_ATOM_XDND_LEAVE;
-             ev.data.data32[0] = _source->win;
-             ev.data.data32[1] = 0;
-
-             xcb_send_event(_ecore_xcb_conn, 0, _source->dest,
-                            XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
-//             ecore_x_flush();
-             _source->state = ECORE_X_DND_SOURCE_IDLE;
-          }
-     }
-   else
-     {
-        ecore_x_selection_xdnd_clear();
-        _source->state = ECORE_X_DND_SOURCE_IDLE;
-     }
-
-   ecore_x_window_ignore_set(_source->win, 0);
-   _source->prev.window = 0;
-
-   return status;
-}
-
 EAPI void
 ecore_x_dnd_aware_set(Ecore_X_Window win,
                       Eina_Bool      on)
@@ -429,10 +375,11 @@ ecore_x_dnd_callback_pos_update_set(void (*cb)(void *, Ecore_X_Xdnd_Position *da
    _posupdatedata = (void *)data;
 }
 
-EAPI Eina_Bool
-ecore_x_dnd_begin(Ecore_X_Window source,
-                  unsigned char *data,
-                  int            size)
+static Eina_Bool
+_ecore_x_dnd_begin(Ecore_X_Window source,
+                   Eina_Bool self;
+                   unsigned char *data,
+                   int            size)
 {
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
 
@@ -452,7 +399,7 @@ ecore_x_dnd_begin(Ecore_X_Window source,
    ecore_x_window_shadow_tree_flush();
 
    _source->win = source;
-   ecore_x_window_ignore_set(_source->win, 1);
+   if (!self) ecore_x_window_ignore_set(_source->win, 1);
    _source->state = ECORE_X_DND_SOURCE_DRAGGING;
    _source->time = _ecore_xcb_events_last_time_get();
    _source->prev.window = 0;
@@ -465,6 +412,88 @@ ecore_x_dnd_begin(Ecore_X_Window source,
    return EINA_TRUE;
 }
 
+static Eina_Bool
+_ecore_x_dnd_drop(Eina_Bool self)
+{
+   xcb_client_message_event_t ev;
+   Eina_Bool status = EINA_FALSE;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+   CHECK_XCB_CONN;
+
+   memset(&ev, 0, sizeof(xcb_client_message_event_t));
+
+   if (_source->dest)
+     {
+        ev.response_type = XCB_CLIENT_MESSAGE;
+        ev.format = 32;
+        ev.window = _source->dest;
+
+        if (_source->will_accept)
+          {
+             ev.type = ECORE_X_ATOM_XDND_DROP;
+             ev.data.data32[0] = _source->win;
+             ev.data.data32[1] = 0;
+             ev.data.data32[2] = _source->time;
+
+             xcb_send_event(_ecore_xcb_conn, 0, _source->dest,
+                            XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
+//             ecore_x_flush();
+             _source->state = ECORE_X_DND_SOURCE_DROPPED;
+             status = EINA_TRUE;
+          }
+        else
+          {
+             ev.type = ECORE_X_ATOM_XDND_LEAVE;
+             ev.data.data32[0] = _source->win;
+             ev.data.data32[1] = 0;
+
+             xcb_send_event(_ecore_xcb_conn, 0, _source->dest,
+                            XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
+//             ecore_x_flush();
+             _source->state = ECORE_X_DND_SOURCE_IDLE;
+          }
+     }
+   else
+     {
+        ecore_x_selection_xdnd_clear();
+        _source->state = ECORE_X_DND_SOURCE_IDLE;
+     }
+
+   if (!self) ecore_x_window_ignore_set(_source->win, 0);
+   _source->prev.window = 0;
+
+   return status;
+}
+
+EAPI Eina_Bool
+ecore_x_dnd_begin(Ecore_X_Window source,
+                  unsigned char *data,
+                  int            size)
+{
+   return _ecore_x_dnd_begin(source, EINA_FALSE, data, size);
+}
+
+EAPI Eina_Bool
+ecore_x_dnd_drop(void)
+{
+   return _ecore_x_dnd_drop(EINA_FALSE);
+}
+
+EAPI Eina_Bool
+ecore_x_dnd_self_begin(Ecore_X_Window source,
+                       unsigned char *data,
+                       int            size)
+{
+   return _ecore_x_dnd_begin(source, EINA_TRUE, data, size);
+}
+
+EAPI Eina_Bool
+ecore_x_dnd_self_drop(void)
+{
+   return _ecore_x_dnd_drop(EINA_TRUE);
+}
+
 EAPI void
 ecore_x_dnd_send_finished(void)
 {
index e4f74a7..e25e936 100644 (file)
@@ -398,10 +398,13 @@ _ecore_x_dnd_target_get(void)
    return _target;
 }
 
-EAPI Eina_Bool
-ecore_x_dnd_begin(Ecore_X_Window source,
-                  unsigned char *data,
-                  int size)
+
+
+static Eina_Bool
+_ecore_x_dnd_begin(Ecore_X_Window source,
+                   Eina_Bool self,
+                   unsigned char *data,
+                   int size)
 {
    LOGFN(__FILE__, __LINE__, __FUNCTION__);
    if (!ecore_x_dnd_version_get(source))
@@ -422,7 +425,7 @@ ecore_x_dnd_begin(Ecore_X_Window source,
    ecore_x_window_shadow_tree_flush();
 
    _source->win = source;
-   ecore_x_window_ignore_set(_source->win, 1);
+   if (!self) ecore_x_window_ignore_set(_source->win, 1);
    _source->state = ECORE_X_DND_SOURCE_DRAGGING;
    _source->time = _ecore_x_event_last_time;
    _source->prev.window = 0;
@@ -435,8 +438,8 @@ ecore_x_dnd_begin(Ecore_X_Window source,
    return EINA_TRUE;
 }
 
-EAPI Eina_Bool
-ecore_x_dnd_drop(void)
+static Eina_Bool
+_ecore_x_dnd_drop(Eina_Bool self)
 {
    XEvent xev;
    int status = EINA_FALSE;
@@ -475,13 +478,41 @@ ecore_x_dnd_drop(void)
         _source->state = ECORE_X_DND_SOURCE_IDLE;
      }
 
-   ecore_x_window_ignore_set(_source->win, 0);
+   if (!self) ecore_x_window_ignore_set(_source->win, 0);
 
    _source->prev.window = 0;
 
    return status;
 }
 
+EAPI Eina_Bool
+ecore_x_dnd_begin(Ecore_X_Window source,
+                  unsigned char *data,
+                  int size)
+{
+   return _ecore_x_dnd_begin(source, EINA_FALSE, data, size);
+}
+
+EAPI Eina_Bool
+ecore_x_dnd_drop(void)
+{
+   return _ecore_x_dnd_drop(EINA_FALSE);
+}
+
+EAPI Eina_Bool
+ecore_x_dnd_self_begin(Ecore_X_Window source,
+                       unsigned char *data,
+                       int size)
+{
+   return _ecore_x_dnd_begin(source, EINA_TRUE, data, size);
+}
+
+EAPI Eina_Bool
+ecore_x_dnd_self_drop(void)
+{
+   return _ecore_x_dnd_drop(EINA_TRUE);
+}
+
 EAPI void
 ecore_x_dnd_send_status(Eina_Bool will_accept,
                         Eina_Bool suppress,
@@ -599,21 +630,29 @@ _ecore_x_dnd_drag(Ecore_X_Window root,
 
    /* Attempt to find a DND-capable window under the cursor */
    skip = ecore_x_window_ignore_list(&num);
+   int i;
+   for (i = 0; i < num; i++) printf("skip %x\n", skip[i]);
 // WARNING - this function is HEAVY. it goes to and from x a LOT walking the
 // window tree - use the SHADOW version - makes a 1-off tree copy, then uses
 // that instead.
 //   win = ecore_x_window_at_xy_with_skip_get(x, y, skip, num);
    win = ecore_x_window_shadow_tree_at_xy_with_skip_get(root, x, y, skip, num);
+   printf("win1 %x\n", win);
 
 // NOTE: This now uses the shadow version to find parent windows
 //   while ((win) && !(ecore_x_dnd_version_get(win)))
 //     win = ecore_x_window_parent_get(win);
    while ((win) && !(ecore_x_dnd_version_get(win)))
-     win = ecore_x_window_shadow_parent_get(root, win);
+     {
+        printf("win parent %x\n", win);
+        win = ecore_x_window_shadow_parent_get(root, win);
+     }
+   printf("win2 %x\n", win);
 
    /* Send XdndLeave to current destination window if we have left it */
    if ((_source->dest) && (win != _source->dest))
      {
+        printf("leave...\n");
         xev.xclient.window = _source->dest;
         xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
         xev.xclient.data.l[0] = _source->win;
@@ -629,6 +668,7 @@ _ecore_x_dnd_drag(Ecore_X_Window root,
 
         _source->version = MIN(ECORE_X_DND_VERSION,
                                ecore_x_dnd_version_get(win));
+        printf("win %x == %x\n", win, _source->dest);
         if (win != _source->dest)
           {
              int i;