ecore_wl2: Add new APIs ecore_wl2_window_frame_callback_add/del()

Abstract frame callbacks through ecore_wl2_window so we can add them in
multiple places without having the wayland compositor generate more than
one.

Also allows us to keep a callback registered over hide/unhide of a window
easily.
This commit is contained in:
Derek Foreman 2017-08-14 17:46:49 -05:00
parent b599b1b900
commit 8f038b2591
3 changed files with 84 additions and 0 deletions

View File

@ -361,6 +361,8 @@ typedef struct Ecore_Wl2_Event_Aux_Message
typedef void (*Ecore_Wl2_Bind_Cb)(struct wl_client *client, void *data, uint32_t version, uint32_t id);
typedef void (*Ecore_Wl2_Unbind_Cb)(struct wl_resource *resource);
typedef void (*Ecore_Wl2_Frame_Cb)(Ecore_Wl2_Window *win, uint32_t timestamp, void *data);
typedef struct _Ecore_Wl2_Frame_Cb_Handle Ecore_Wl2_Frame_Cb_Handle;
EAPI extern int ECORE_WL2_EVENT_DISCONNECT; /** @since 1.18 */
EAPI extern int ECORE_WL2_EVENT_CONNECT; /** @since 1.18 */
@ -1902,6 +1904,27 @@ EAPI void ecore_wl2_window_commit(Ecore_Wl2_Window *window, Eina_Bool flush);
*/
EAPI Eina_Bool ecore_wl2_window_pending_get(Ecore_Wl2_Window *window);
/**
* Add a callback that fires when the window's surface_frame callback fires
*
* @window the window to add a callback on
* @cb The callback
* @data user data to provide to the callback handler
*
* @since 1.20
*/
EAPI Ecore_Wl2_Frame_Cb_Handle *ecore_wl2_window_frame_callback_add(Ecore_Wl2_Window *window, Ecore_Wl2_Frame_Cb cb, void *data);
/**
* delete a callback that fires when the window's surface_frame callback fires
*
* @window the window to add a callback on
* @cb The callback handle
*
* @since 1.20
*/
EAPI void ecore_wl2_window_frame_callback_del(Ecore_Wl2_Frame_Cb_Handle *handle);
# endif
# undef EAPI

View File

@ -140,6 +140,13 @@ struct _Ecore_Wl2_Aux_Hint
const char *hint, *val;
};
struct _Ecore_Wl2_Frame_Cb_Handle
{
Ecore_Wl2_Window *win;
Ecore_Wl2_Frame_Cb cb;
void *data;
};
struct _Ecore_Wl2_Window
{
EINA_INLIST;
@ -184,6 +191,7 @@ struct _Ecore_Wl2_Window
Eina_Inlist *subsurfs;
Eina_List *supported_aux_hints;
Eina_List *frame_callbacks;
Eina_Bool moving : 1;
Eina_Bool minimized : 1;

View File

@ -538,6 +538,12 @@ ecore_wl2_window_hide(Ecore_Wl2_Window *window)
window->commit_pending = EINA_FALSE;
}
if (window->callback)
{
wl_callback_destroy(window->callback);
window->callback = NULL;
}
window->configure_serial = 0;
window->zxdg_configure_ack = NULL;
window->zxdg_set_min_size = NULL;
@ -573,6 +579,9 @@ ecore_wl2_window_free(Ecore_Wl2_Window *window)
_ecore_wl2_window_aux_hint_free(window);
if (window->callback) wl_callback_destroy(window->callback);
window->callback = NULL;
if (window->uuid && window->surface && window->display->wl.session_recovery)
zwp_e_session_recovery_destroy_uuid(window->display->wl.session_recovery,
window->surface, window->uuid);
@ -1344,6 +1353,26 @@ ecore_wl2_window_aspect_set(Ecore_Wl2_Window *window, int w, int h, unsigned int
efl_hints_set_aspect(window->display->wl.efl_hints, window->zxdg_toplevel, w, h, aspect);
}
static void
_frame_cb(void *data, struct wl_callback *callback, uint32_t timestamp)
{
Ecore_Wl2_Frame_Cb_Handle *cb;
Ecore_Wl2_Window *window;
Eina_List *l, *ll;
window = data;
window->commit_pending = EINA_FALSE;
wl_callback_destroy(callback);
window->callback = NULL;
EINA_LIST_FOREACH_SAFE(window->frame_callbacks, l, ll, cb)
cb->cb(window, timestamp, cb->data);
}
static struct wl_callback_listener _frame_listener =
{
_frame_cb
};
EAPI void ecore_wl2_window_commit(Ecore_Wl2_Window *window, Eina_Bool flush)
{
EINA_SAFETY_ON_NULL_RETURN(window);
@ -1364,3 +1393,27 @@ EAPI Eina_Bool ecore_wl2_window_pending_get(Ecore_Wl2_Window *window)
return window->commit_pending;
}
EAPI Ecore_Wl2_Frame_Cb_Handle *ecore_wl2_window_frame_callback_add(Ecore_Wl2_Window *window, Ecore_Wl2_Frame_Cb cb, void *data)
{
Ecore_Wl2_Frame_Cb_Handle *callback;
EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(cb, NULL);
callback = malloc(sizeof(*callback));
EINA_SAFETY_ON_NULL_RETURN_VAL(callback, NULL);
callback->cb = cb;
callback->data = data;
callback->win = window;
window->frame_callbacks = eina_list_append(window->frame_callbacks, callback);
return callback;
}
EAPI void ecore_wl2_window_frame_callback_del(Ecore_Wl2_Frame_Cb_Handle *handle)
{
EINA_SAFETY_ON_NULL_RETURN(handle);
handle->win->frame_callbacks = eina_list_remove(handle->win->frame_callbacks, handle);
free(handle);
}