Add ecore_x_dnd_self_begin() and ecore_x_dnd_self_drop() to allow dnd

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.
This commit is contained in:
Carsten Haitzler 2013-02-21 16:49:10 +09:00
parent 5e99f9b968
commit 83190eb0c2
5 changed files with 147 additions and 69 deletions

View File

@ -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.

2
NEWS
View File

@ -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.

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

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

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