Dnd updates

Add skip function for window get
Add ignore window list.


SVN revision: 17316
This commit is contained in:
sebastid 2005-10-08 12:40:14 +00:00 committed by sebastid
parent aa0bd546dd
commit a4c3c2868f
3 changed files with 140 additions and 25 deletions

View 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,

View 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);

View 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
*
@ -272,6 +275,62 @@ ecore_x_window_del(Ecore_X_Window win)
XDestroyWindow(_ecore_x_disp, 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.
@ -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;