diff --git a/ChangeLog b/ChangeLog index f693ee63a9..1ae0ace285 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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. diff --git a/NEWS b/NEWS index b0d312323f..67913fbfa1 100644 --- a/NEWS +++ b/NEWS @@ -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. diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h index 464432d8d3..64f24277cd 100644 --- a/src/lib/ecore_x/Ecore_X.h +++ b/src/lib/ecore_x/Ecore_X.h @@ -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); diff --git a/src/lib/ecore_x/xcb/ecore_xcb_dnd.c b/src/lib/ecore_x/xcb/ecore_xcb_dnd.c index 80ae6b4c5d..543f43c6c9 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_dnd.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_dnd.c @@ -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) { diff --git a/src/lib/ecore_x/xlib/ecore_x_dnd.c b/src/lib/ecore_x/xlib/ecore_x_dnd.c index e4f74a7257..e25e93617b 100644 --- a/src/lib/ecore_x/xlib/ecore_x_dnd.c +++ b/src/lib/ecore_x/xlib/ecore_x_dnd.c @@ -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;