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) 2013-02-20 Carsten Haitzler (The Rasterman)
* Fix ecore-x edid fetch to ftech 128, not 100 bytes. * Fix ecore-x edid fetch to ftech 128, not 100 bytes.
2013-02-20 Cedric Bail 2013-02-20 Cedric Bail
* Properly report file not found in Edje. * 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_e_window_profile_change_done_send()
ecore_x_randr_crtc_info_get() ecore_x_randr_crtc_info_get()
ecore_x_randr_crtc_info_free() ecore_x_randr_crtc_info_free()
ecore_x_dnd_self_begin()
ecore_x_dnd_self_drop()
* ecore_wayland: * ecore_wayland:
- Store global wayland interfaces in a globals list so wayland programs - Store global wayland interfaces in a globals list so wayland programs
can bind to other non-standard wayland protocol extensions. 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 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_begin(Ecore_X_Window source, unsigned char *data, int size);
EAPI Eina_Bool ecore_x_dnd_drop(void); 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_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_send_finished(void);
EAPI void ecore_x_dnd_source_action_set(Ecore_X_Atom action); 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(); // 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 EAPI void
ecore_x_dnd_aware_set(Ecore_X_Window win, ecore_x_dnd_aware_set(Ecore_X_Window win,
Eina_Bool on) 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; _posupdatedata = (void *)data;
} }
EAPI Eina_Bool static Eina_Bool
ecore_x_dnd_begin(Ecore_X_Window source, _ecore_x_dnd_begin(Ecore_X_Window source,
unsigned char *data, Eina_Bool self;
int size) unsigned char *data,
int size)
{ {
LOGFN(__FILE__, __LINE__, __FUNCTION__); LOGFN(__FILE__, __LINE__, __FUNCTION__);
@ -452,7 +399,7 @@ ecore_x_dnd_begin(Ecore_X_Window source,
ecore_x_window_shadow_tree_flush(); ecore_x_window_shadow_tree_flush();
_source->win = source; _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->state = ECORE_X_DND_SOURCE_DRAGGING;
_source->time = _ecore_xcb_events_last_time_get(); _source->time = _ecore_xcb_events_last_time_get();
_source->prev.window = 0; _source->prev.window = 0;
@ -465,6 +412,88 @@ ecore_x_dnd_begin(Ecore_X_Window source,
return EINA_TRUE; 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 EAPI void
ecore_x_dnd_send_finished(void) ecore_x_dnd_send_finished(void)
{ {

View File

@ -398,10 +398,13 @@ _ecore_x_dnd_target_get(void)
return _target; return _target;
} }
EAPI Eina_Bool
ecore_x_dnd_begin(Ecore_X_Window source,
unsigned char *data, static Eina_Bool
int size) _ecore_x_dnd_begin(Ecore_X_Window source,
Eina_Bool self,
unsigned char *data,
int size)
{ {
LOGFN(__FILE__, __LINE__, __FUNCTION__); LOGFN(__FILE__, __LINE__, __FUNCTION__);
if (!ecore_x_dnd_version_get(source)) 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(); ecore_x_window_shadow_tree_flush();
_source->win = source; _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->state = ECORE_X_DND_SOURCE_DRAGGING;
_source->time = _ecore_x_event_last_time; _source->time = _ecore_x_event_last_time;
_source->prev.window = 0; _source->prev.window = 0;
@ -435,8 +438,8 @@ ecore_x_dnd_begin(Ecore_X_Window source,
return EINA_TRUE; return EINA_TRUE;
} }
EAPI Eina_Bool static Eina_Bool
ecore_x_dnd_drop(void) _ecore_x_dnd_drop(Eina_Bool self)
{ {
XEvent xev; XEvent xev;
int status = EINA_FALSE; int status = EINA_FALSE;
@ -475,13 +478,41 @@ ecore_x_dnd_drop(void)
_source->state = ECORE_X_DND_SOURCE_IDLE; _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; _source->prev.window = 0;
return status; 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 EAPI void
ecore_x_dnd_send_status(Eina_Bool will_accept, ecore_x_dnd_send_status(Eina_Bool will_accept,
Eina_Bool suppress, 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 */ /* Attempt to find a DND-capable window under the cursor */
skip = ecore_x_window_ignore_list(&num); 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 // 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 // window tree - use the SHADOW version - makes a 1-off tree copy, then uses
// that instead. // that instead.
// win = ecore_x_window_at_xy_with_skip_get(x, y, skip, num); // 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); 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 // NOTE: This now uses the shadow version to find parent windows
// while ((win) && !(ecore_x_dnd_version_get(win))) // while ((win) && !(ecore_x_dnd_version_get(win)))
// win = ecore_x_window_parent_get(win); // win = ecore_x_window_parent_get(win);
while ((win) && !(ecore_x_dnd_version_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 */ /* Send XdndLeave to current destination window if we have left it */
if ((_source->dest) && (win != _source->dest)) if ((_source->dest) && (win != _source->dest))
{ {
printf("leave...\n");
xev.xclient.window = _source->dest; xev.xclient.window = _source->dest;
xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE; xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
xev.xclient.data.l[0] = _source->win; 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, _source->version = MIN(ECORE_X_DND_VERSION,
ecore_x_dnd_version_get(win)); ecore_x_dnd_version_get(win));
printf("win %x == %x\n", win, _source->dest);
if (win != _source->dest) if (win != _source->dest)
{ {
int i; int i;