Xdnd callback (API Addition): Rationale below.

Essentially the problem is this: For drag and drop Ecore currently handles the
position update calls.  But usually the application wants to display some user
feedback - a window to display the drag selection for instance.

Now the way e17 does it is grab the mouse cursor movements and track them
itself.  However ecore is already doing this, it's already walking window
trees, calculating real positions, _and_ sending them in an X client message.
So it seems rather silly to duplicate the code in the user app to get the same
info.

We could possibly have added a new event, but then we need to deal the fact
the position update may arrive _After_ the item has been dropped.  Hilarity
ensures[1].

This callback is meant for purely the selection owner of the drag to use, so
it is a callback set, not an add.

[1] Segfaults probably.  Nothing funnier.

SVN revision: 52181
This commit is contained in:
Brett Nash 2010-09-13 09:15:50 +00:00
parent 310ee61355
commit e36847a0ab
2 changed files with 50 additions and 0 deletions

View File

@ -334,6 +334,7 @@ typedef struct _Ecore_X_Event_Xdnd_Status Ecore_X_Event_Xdnd_Status;
typedef struct _Ecore_X_Event_Xdnd_Leave Ecore_X_Event_Xdnd_Leave;
typedef struct _Ecore_X_Event_Xdnd_Drop Ecore_X_Event_Xdnd_Drop;
typedef struct _Ecore_X_Event_Xdnd_Finished Ecore_X_Event_Xdnd_Finished;
typedef struct _Ecore_X_Xdnd_Position Ecore_X_Xdnd_Position;
typedef struct _Ecore_X_Event_Client_Message Ecore_X_Event_Client_Message;
typedef struct _Ecore_X_Event_Window_Shape Ecore_X_Event_Window_Shape;
typedef struct _Ecore_X_Event_Screensaver_Notify Ecore_X_Event_Screensaver_Notify;
@ -646,6 +647,15 @@ struct _Ecore_X_Event_Xdnd_Position
Ecore_X_Atom action;
};
struct _Ecore_X_Xdnd_Position
{
Ecore_X_Window win, prev;
struct
{
int x, y;
} position;
};
struct _Ecore_X_Event_Xdnd_Status
{
Ecore_X_Window win, target;

View File

@ -28,6 +28,8 @@ typedef struct _Version_Cache_Item
} Version_Cache_Item;
static Version_Cache_Item *_version_cache = NULL;
static int _version_cache_num = 0, _version_cache_alloc = 0;
static void (*_posupdatecb)(void *, Ecore_X_Xdnd_Position *);
static void *_posupdatedata;
void
_ecore_x_dnd_init(void)
@ -339,6 +341,29 @@ ecore_x_dnd_actions_set(Ecore_X_Window win,
}
} /* ecore_x_dnd_actions_set */
/**
* The DND position update cb is called Ecore_X sends a DND position to a
* client.
*
* It essentially mirrors some of the data sent in the position message.
* Generally this cb should be set just before position update is called.
* Please note well you need to look after your own data pointer if someone
* trashes you position update cb set.
*
* It is considered good form to clear this when the dnd event finishes.
*
* @param cb Callback to updated each time ecore_x sends a position update.
* @param data User data.
*/
EAPI void
ecore_x_dnd_position_update_cb_set(
void (*cb)(void *, Ecore_X_Xdnd_Position *data),
void *data)
{
_posupdatecb = cb;
_posupdatedata = data;
}
Ecore_X_DND_Source *
_ecore_x_dnd_source_get(void)
{
@ -534,6 +559,7 @@ _ecore_x_dnd_drag(Ecore_X_Window root, int x, int y)
XEvent xev;
Ecore_X_Window win;
Ecore_X_Window *skip;
Ecore_X_Xdnd_Position pos;
int num;
if (_source->state != ECORE_X_DND_SOURCE_DRAGGING)
@ -636,9 +662,23 @@ _ecore_x_dnd_drag(Ecore_X_Window root, int x, int y)
}
}
if (_posupdatecb)
{
pos.position.x = x;
pos.position.y = y;
pos.win = win;
pos.prev = _source->dest;
_posupdatecb(_posupdatedata, &pos);
}
_source->prev.x = x;
_source->prev.y = y;
_source->prev.window = root;
_source->dest = win;
} /* _ecore_x_dnd_drag */
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/