Dnd updates
authorsebastid <sebastid>
Sat, 8 Oct 2005 12:40:14 +0000 (12:40 +0000)
committersebastid <sebastid@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 8 Oct 2005 12:40:14 +0000 (12:40 +0000)
Add skip function for window get
Add ignore window list.

SVN revision: 17316

legacy/ecore/src/lib/ecore_x/Ecore_X.h
legacy/ecore/src/lib/ecore_x/ecore_x_dnd.c
legacy/ecore/src/lib/ecore_x/ecore_x_window.c

index 389c8f1..fe07446 100644 (file)
@@ -988,7 +988,7 @@ EAPI int              ecore_x_dnd_type_isset(Ecore_X_Window win, const char *typ
 EAPI void             ecore_x_dnd_type_set(Ecore_X_Window win, const char *type, int on);
 EAPI void             ecore_x_dnd_types_set(Ecore_X_Window win, char **types, unsigned int num_types);
 EAPI int              ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size);
-EAPI void             ecore_x_dnd_drop(void);
+EAPI int              ecore_x_dnd_drop(void);
 EAPI void             ecore_x_dnd_send_status(int will_accept, int suppress, Ecore_X_Rectangle rectangle, Ecore_X_Atom action);
 EAPI void             ecore_x_dnd_send_finished(void);
                  
@@ -1004,6 +1004,9 @@ EAPI void             ecore_x_window_configure(Ecore_X_Window win,
 EAPI void             ecore_x_window_cursor_set(Ecore_X_Window win,
                                                Ecore_X_Cursor c);
 EAPI void             ecore_x_window_del(Ecore_X_Window win);
+EAPI void             ecore_x_window_ignore_set(Ecore_X_Window win, int ignore);
+EAPI Ecore_X_Window  *ecore_x_window_ignore_list(int *num);
+
 EAPI void             ecore_x_window_delete_request_send(Ecore_X_Window win);
 EAPI void             ecore_x_window_show(Ecore_X_Window win);
 EAPI void             ecore_x_window_hide(Ecore_X_Window win);
@@ -1025,6 +1028,7 @@ EAPI void             ecore_x_window_cursor_show(Ecore_X_Window win, int show);
 EAPI void             ecore_x_window_defaults_set(Ecore_X_Window win);
 EAPI int              ecore_x_window_visible_get(Ecore_X_Window win);
 EAPI Ecore_X_Window   ecore_x_window_at_xy_get(int x, int y);
+EAPI Ecore_X_Window   ecore_x_window_at_xy_with_skip_get(int x, int y, Ecore_X_Window *skip, int skip_num);
 EAPI Ecore_X_Window   ecore_x_window_parent_get(Ecore_X_Window win);
 
 EAPI void             ecore_x_window_background_color_set(Ecore_X_Window win,
index 748e367..b6284a5 100644 (file)
@@ -210,6 +210,7 @@ ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size)
      return 0;
 
    _source->win = source;
+   ecore_x_window_ignore_set(_source->win, 1);
    printf("source: 0x%x\n", source);
    _source->state = ECORE_X_DND_SOURCE_DRAGGING;
    _source->time = _ecore_x_event_last_time;
@@ -220,10 +221,11 @@ ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size)
    return 1;
 }
 
-void
+int
 ecore_x_dnd_drop(void)
 {
    XEvent xev;
+   int status = 0;
 
    if (_source->dest)
      {
@@ -240,6 +242,7 @@ ecore_x_dnd_drop(void)
             xev.xclient.data.l[2] = _source->time;
             XSendEvent(_ecore_x_disp, _source->dest, False, 0, &xev);
             _source->state = ECORE_X_DND_SOURCE_DROPPED;
+            status = 1;
          }
        else
          {
@@ -256,6 +259,8 @@ ecore_x_dnd_drop(void)
        ecore_x_selection_xdnd_clear();
        _source->state = ECORE_X_DND_SOURCE_IDLE;
      }
+   ecore_x_window_ignore_set(_source->win, 0);
+   return status;
 }
 
 void
@@ -335,8 +340,10 @@ ecore_x_dnd_send_finished(void)
 void
 _ecore_x_dnd_drag(int x, int y)
 {
-   XEvent         xev;
-   Ecore_X_Window win;
+   XEvent          xev;
+   Ecore_X_Window  win;
+   Ecore_X_Window *skip;
+   int             num;
 
    if (_source->state != ECORE_X_DND_SOURCE_DRAGGING)
      return;
@@ -348,7 +355,8 @@ _ecore_x_dnd_drag(int x, int y)
    xev.xclient.format = 32;
 
    /* Attempt to find a DND-capable window under the cursor */
-   win = ecore_x_window_at_xy_get(x, y);
+   skip = ecore_x_window_ignore_list(&num);
+   win = ecore_x_window_at_xy_with_skip_get(x, y, skip, num);
    while ((win) && !(ecore_x_dnd_version_get(win)))
      win = ecore_x_window_parent_get(win);
 
index e0fddbd..a2c20de 100644 (file)
@@ -6,6 +6,9 @@
 #include "Ecore_X.h"
 #include "Ecore_X_Atoms.h"
 
+static int             ignore_num = 0;
+static Ecore_X_Window *ignore_list = NULL;
+
 /**
  * @defgroup Ecore_X_Window_Create_Group X Window Creation Functions
  *
@@ -273,6 +276,62 @@ ecore_x_window_del(Ecore_X_Window win)
 }
 
 /**
+ * Set if a window should be ignored.
+ * @param   win The given window.
+ * @param   ignore if to ignore
+ */
+void
+ecore_x_window_ignore_set(Ecore_X_Window win, int ignore)
+{
+   int i, j;
+
+   if (ignore)
+     {
+       if (ignore_list)
+         {
+            for (i = 0; i < ignore_num; i++)
+              {
+                 if (win == ignore_list[i])
+                   return;
+              }
+            ignore_list = realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window));
+            if (!ignore_list) return;
+            ignore_list[ignore_num++] = win;
+         }
+       else
+         {
+            ignore_num = 0;
+            ignore_list = malloc(sizeof(Ecore_X_Window));
+            ignore_list[ignore_num++] = win;
+         }
+     }
+   else
+     {
+       if (!ignore_list) return;
+       for (i = 0, j = 0; i < ignore_num; i++)
+         {
+            if (win != ignore_list[i])
+              ignore_list[i] = ignore_list[j++];
+            else
+              ignore_num--;
+         }
+       ignore_list = realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window));
+     }
+}
+
+/**
+ * Get the ignore list
+ * @param   num number of windows in the list
+ * @return  list of windows to ignore
+ */
+Ecore_X_Window *
+ecore_x_window_ignore_list(int *num)
+{
+   if (num) *num = ignore_num;
+   return ignore_list;
+}
+
+/**
  * Sends a delete request to the given window.
  * @param   win The given window.
  * @ingroup Evas_X_Window_Destroy_Group
@@ -626,40 +685,60 @@ ecore_x_window_visible_get(Ecore_X_Window win)
 }
 
 static Window
-_ecore_x_window_at_xy_get(Window base, int bx, int by, int x, int y)
+_ecore_x_window_at_xy_get(Window base, int bx, int by, int x, int y,
+                         Ecore_X_Window *skip, int skip_num)
 {
    Window           *list = NULL;
    Window            parent_win = 0, child = 0, root_win = 0;
-   int               i, wx, wy, ww, wh;
+   int               i, j, wx, wy, ww, wh;
    unsigned int      num;
 
    if (!ecore_x_window_visible_get(base))
-      return 0;
+     return 0;
 
    ecore_x_window_geometry_get(base, &wx, &wy, &ww, &wh);
    wx += bx;
    wy += by;
 
    if (!((x >= wx) && (y >= wy) && (x < (wx + ww)) && (y < (wy + wh))))
-      return 0;
-   
+     return 0;
+
    if (!XQueryTree(_ecore_x_disp, base, &root_win, &parent_win, &list, &num))
-      return base;
+     {
+       if (skip)
+         {
+            for (i = 0; i < skip_num; i++)
+              if (base == skip[i])
+                return 0;
+         }
+       return base;
+     }
 
    if (list)
-   {
-      for (i = num - 1;; --i)
-      {
-         if ((child = _ecore_x_window_at_xy_get(list[i], wx, wy, x, y)))
-         {
-            XFree(list);
-            return child;
-         }
-         if (!i)
-            break;
-      }
-      XFree(list);
-   }
+     {
+       for (i = num - 1; i >= 0; --i)
+         {
+            if (skip)
+              {
+                 for (j = 0; j < skip_num; j++)
+                   if (list[i] == skip[j])
+                     continue;
+              }
+            if ((child = _ecore_x_window_at_xy_get(list[i], wx, wy, x, y, skip, skip_num)))
+              {
+                 XFree(list);
+                 return child;
+              }
+         }
+       XFree(list);
+     }
+
+   if (skip)
+     {
+       for (i = 0; i < skip_num; i++)
+         if (base == skip[i])
+           return 0;
+     }
 
    return base;
 }
@@ -681,7 +760,31 @@ ecore_x_window_at_xy_get(int x, int y)
    root = DefaultRootWindow(_ecore_x_disp);
    
    ecore_x_grab();
-   win = _ecore_x_window_at_xy_get(root, 0, 0, x, y);
+   win = _ecore_x_window_at_xy_get(root, 0, 0, x, y, NULL, 0);
+   ecore_x_ungrab();
+   
+   return win ? win : root;
+}
+
+/**
+ * Retrieves the top, visible window at the given location,
+ * but skips the windows in the list.
+ * @param   x The given X position.
+ * @param   y The given Y position.
+ * @return  The window at that position.
+ * @ingroup Ecore_X_Window_Geometry_Group
+ */
+Ecore_X_Window
+ecore_x_window_at_xy_with_skip_get(int x, int y, Ecore_X_Window *skip, int skip_num)
+{
+   Ecore_X_Window    win, root;
+   
+   /* FIXME: Proper function to determine current root/virtual root
+    * window missing here */
+   root = DefaultRootWindow(_ecore_x_disp);
+   
+   ecore_x_grab();
+   win = _ecore_x_window_at_xy_get(root, 0, 0, x, y, skip, skip_num);
    ecore_x_ungrab();
    
    return win ? win : root;