improve cnp to tell you when you lost a selection and track obj

deletions.



SVN revision: 72798
This commit is contained in:
Carsten Haitzler 2012-06-25 11:16:25 +00:00
parent cab76c1f57
commit af564b3dc7
3 changed files with 326 additions and 206 deletions

View File

@ -215,3 +215,10 @@
* Genlist: Fixed tree expand bug. Check item type when an item is requested
to be expanded/contracted.
2012-06-25 Carsten Haitzler (The Rasterman)
* add elm_cnp_selection_loss_callback_set() so you know when you
lose a selection as a client
* improve robustness of cnp to track target object deletions.

View File

@ -42,7 +42,7 @@
#define ARRAYINIT(foo) [foo] =
#define DEBUGON 1
//#define DEBUGON 1
#ifdef DEBUGON
# define cnp_debug(x...) fprintf(stderr, __FILE__": " x)
@ -102,6 +102,8 @@ struct _Cnp_Selection
Eina_Bool (*set) (Ecore_X_Window, const void *data, int size);
Eina_Bool (*clear) (void);
void (*request) (Ecore_X_Window, const char *target);
Elm_Selection_Loss_Cb loss_cb;
void *loss_data;
Elm_Sel_Format format;
Ecore_X_Selection ecore_sel;
@ -447,6 +449,22 @@ _elm_widget_xwin_get(const Evas_Object *obj)
}
#endif
#ifdef HAVE_ELEMENTARY_X
static void
_sel_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
Cnp_Selection *sel = data;
if (sel->widget == obj) sel->widget = NULL;
}
static void
_sel_obj_del2(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
Cnp_Selection *sel = data;
if (sel->requestwidget == obj) sel->requestwidget = NULL;
}
#endif
EAPI Eina_Bool
elm_cnp_selection_set(Evas_Object *obj, Elm_Sel_Type selection,
Elm_Sel_Format format, const void *selbuf, size_t buflen)
@ -463,11 +481,23 @@ elm_cnp_selection_set(Evas_Object *obj, Elm_Sel_Type selection,
sel = selections + selection;
if (sel->loss_cb) sel->loss_cb(sel->loss_data, selection);
if (sel->widget)
evas_object_event_callback_del_full(sel->widget, EVAS_CALLBACK_DEL,
_sel_obj_del, sel);
sel->widget = NULL;
sel->active = EINA_TRUE;
sel->widget = obj;
sel->xwin = xwin;
sel->set(xwin, &selection, sizeof(Elm_Sel_Type));
sel->format = format;
sel->loss_cb = NULL;
sel->loss_data = NULL;
evas_object_event_callback_add
(sel->widget, EVAS_CALLBACK_DEL, _sel_obj_del, sel);
if (selbuf)
{
@ -494,6 +524,19 @@ elm_cnp_selection_set(Evas_Object *obj, Elm_Sel_Type selection,
#endif
}
EAPI void
elm_cnp_selection_loss_callback_set(Elm_Sel_Type selection, Elm_Selection_Loss_Cb func, const void *data)
{
#ifdef HAVE_ELEMENTARY_X
Cnp_Selection *sel;
if (selection > ELM_SEL_TYPE_CLIPBOARD) return;
sel = selections + selection;
sel->loss_cb = func;
sel->loss_data = (void *)data;
#endif
}
EAPI Eina_Bool
elm_object_cnp_selection_clear(Evas_Object *obj, Elm_Sel_Type selection)
{
@ -509,8 +552,18 @@ elm_object_cnp_selection_clear(Evas_Object *obj, Elm_Sel_Type selection)
/* No longer this selection: Consider it gone! */
if ((!sel->active) || (sel->widget != obj)) return EINA_TRUE;
sel->active = EINA_FALSE;
if (sel->widget)
evas_object_event_callback_del_full(sel->widget, EVAS_CALLBACK_DEL,
_sel_obj_del, sel);
if (sel->requestwidget)
evas_object_event_callback_del_full(sel->requestwidget, EVAS_CALLBACK_DEL,
_sel_obj_del2, sel);
sel->widget = NULL;
sel->requestwidget = NULL;
sel->loss_cb = NULL;
sel->loss_data = NULL;
sel->active = EINA_FALSE;
if (sel->selbuf)
{
free(sel->selbuf);
@ -539,6 +592,11 @@ elm_cnp_selection_get(Evas_Object *obj, Elm_Sel_Type selection,
sel = selections + selection;
if (!xwin) return EINA_FALSE;
if (sel->requestwidget)
evas_object_event_callback_del_full(sel->requestwidget, EVAS_CALLBACK_DEL,
_sel_obj_del2, sel);
sel->requestwidget = NULL;
sel->requestformat = format;
sel->requestwidget = obj;
sel->xwin = xwin;
@ -546,6 +604,9 @@ elm_cnp_selection_get(Evas_Object *obj, Elm_Sel_Type selection,
sel->datacb = datacb;
sel->udata = udata;
evas_object_event_callback_add
(sel->requestwidget, EVAS_CALLBACK_DEL, _sel_obj_del2, sel);
return EINA_TRUE;
#else
return EINA_FALSE;
@ -590,6 +651,18 @@ selection_clear(void *udata __UNUSED__, int type __UNUSED__, void *event)
if (i > ELM_SEL_TYPE_CLIPBOARD) return ECORE_CALLBACK_PASS_ON;
sel = selections + i;
if (sel->loss_cb) sel->loss_cb(sel->loss_data, i);
if (sel->widget)
evas_object_event_callback_del_full(sel->widget, EVAS_CALLBACK_DEL,
_sel_obj_del, sel);
if (sel->requestwidget)
evas_object_event_callback_del_full(sel->requestwidget, EVAS_CALLBACK_DEL,
_sel_obj_del2, sel);
sel->widget = NULL;
sel->requestwidget = NULL;
sel->active = EINA_FALSE;
sel->widget = NULL;
if (sel->selbuf)

View File

@ -97,6 +97,15 @@ typedef struct _Elm_Selection_Data Elm_Selection_Data;
*/
typedef Eina_Bool (*Elm_Drop_Cb)(void *data, Evas_Object *obj, Elm_Selection_Data *ev);
/**
* Callback invoked in when the selection ownership for a given selection is lost.
*
* @param data Application specific data
* @param selection The selection that is lost
* @since 1.1
*/
typedef void (*Elm_Selection_Loss_Cb)(void *data, Elm_Sel_Type selection);
/**
* @brief Set copy data for a widget.
@ -158,6 +167,37 @@ EAPI Eina_Bool elm_cnp_selection_get(Evas_Object *obj, Elm_Sel_Type selection,
EAPI Eina_Bool elm_object_cnp_selection_clear(Evas_Object *obj,
Elm_Sel_Type selection);
/**
* @brief Set a function to be called when a selection is lost
*
* The function @p func is set of be called when selection @p selection is lost
* to another process or when elm_cnp_selection_set() is called. If @p func
* is NULL then it is not called. @p data is passed as the data parameter to
* the callback functions and selection is passed in as the selection that
* has been lost.
*
* elm_cnp_selection_set() and elm_object_cnp_selection_clear() automatically
* set this los callback to NULL when called. If you wish to take the selection
* and then be notified of loss please do this (for example):
*
* @code
* elm_cnp_selection_set(obj, ELM_SEL_TYPE_PRIMARY, ELM_SEL_FORMAT_TEXT, "hello", strlen(hello));
* elm_cnp_selection_loss_callback_set(ELM_SEL_TYPE_PRIMARY, loss_cb, NULL);
* @endcode
*
* @see also elm_cnp_selection_set()
*
* @param selection Selection to be notified of for loss
* @param func The function to call
* @param data The data pointer passed to the function.
*
* @ingroup CopyPaste
*
* @since 1.1
*/
EAPI void elm_cnp_selection_loss_callback_set(Elm_Sel_Type selection, Elm_Selection_Loss_Cb func, const void *data);
/**
* @}
*/