struct wl_listener surface_destroy;
struct wl_listener parent_surface_destroy;
struct wl_listener cached;
+ struct wl_listener sync_precommit;
+ struct wl_listener desync_precommit;
struct wl_listener request_move;
struct
{
struct wl_signal destroy;
struct wl_signal cached;
+ struct wl_signal sync_precommit;
+ struct wl_signal desync_precommit;
} events;
};
static void _e_subsurface_position_update(E_Subsurface *sub);
static void _e_subsurface_cb_destroy(struct wl_listener *listener, void *data);
static void _e_subsurface_cb_cached(struct wl_listener *listener, void *data);
+static void _e_subsurface_cb_sync_precommit(struct wl_listener *listener, void *data);
+static void _e_subsurface_cb_desync_precommit(struct wl_listener *listener, void *data);
static void _e_subsurface_cb_request_move(struct wl_listener *listener, void *data);
static void _e_subsurface_cb_surface_destroy(struct wl_listener *listener, void *data);
static void _e_subsurface_cb_parent_surface_destroy(struct wl_listener *listener, void *data);
_e_surface_cb_commit(struct wl_listener *listener, void *data)
{
E_Surface *surface;
- E_Subsurface *sub;
surface = wl_container_of(listener, surface, commit);
if (e_comp_wl_remote_surface_commit(surface->ec)) return;
- sub = _e_subsurface_from_surface(surface);
- if (sub)
- _e_subsurface_commit(sub);
- else
- _e_surface_commit(surface);
+ _e_surface_commit(surface);
}
static void
wl_signal_init(&sub->events.destroy);
wl_signal_init(&sub->events.cached);
+ wl_signal_init(&sub->events.sync_precommit);
+ wl_signal_init(&sub->events.desync_precommit);
sub->ds_subsurface = ds_subsurface;
sub->destroy.notify = _e_subsurface_cb_destroy;
sub->cached.notify = _e_subsurface_cb_cached;
wl_signal_add(&ds_subsurface->events.cached, &sub->cached);
+ sub->sync_precommit.notify = _e_subsurface_cb_sync_precommit;
+ ds_surface_add_sync_precommit_listener(ds_subsurface->surface, &sub->sync_precommit);
+
+ sub->desync_precommit.notify = _e_subsurface_cb_desync_precommit;
+ ds_surface_add_desync_precommit_listener(ds_subsurface->surface, &sub->desync_precommit);
+
sub->request_move.notify = _e_subsurface_cb_request_move;
wl_signal_add(&ds_subsurface->events.request_move, &sub->request_move);
wl_signal_emit(&sub->events.destroy, sub);
e_comp_wl_client_subsurface_finish(sub->surface->ec);
+ wl_list_remove(&sub->desync_precommit.link);
+ wl_list_remove(&sub->sync_precommit.link);
wl_list_remove(&sub->request_move.link);
wl_list_remove(&sub->parent_surface_destroy.link);
wl_list_remove(&sub->cached.link);
}
static void
+_e_subsurface_cb_sync_precommit(struct wl_listener *listener, void *data)
+{
+ E_Subsurface *sub;
+
+ sub = wl_container_of(listener, sub, sync_precommit);
+
+ wl_signal_emit(&sub->events.sync_precommit, sub);
+
+ if (sub->base.cached.has_data)
+ {
+ e_presentation_time_container_feedback_discard(&sub->surface->base.presentation_container);
+ e_presentation_time_container_feedback_merge(&sub->surface->base.presentation_container,
+ &sub->base.cached.presentation_container);
+ sub->base.cached.has_data = EINA_FALSE;
+ }
+
+ // The _e_subsurface_synchronized_check() should be called, because this
+ // callback could be called due to the wl_subsurface.set_desync()
+ if (_e_subsurface_synchronized_check(sub))
+ {
+ e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_SYNCHRONIZED_COMMIT,
+ sub->surface->ec);
+ }
+}
+
+static void
+_e_subsurface_cb_desync_precommit(struct wl_listener *listener, void *data)
+{
+ E_Subsurface *sub;
+
+ sub = wl_container_of(listener, sub, desync_precommit);
+
+ wl_signal_emit(&sub->events.desync_precommit, sub);
+
+ if (sub->base.cached.has_data)
+ {
+ e_presentation_time_container_feedback_discard(&sub->base.cached.presentation_container);
+ e_presentation_time_container_feedback_merge(&sub->base.cached.presentation_container,
+ &sub->surface->base.pending.presentation_container);
+
+ e_presentation_time_container_feedback_discard(&sub->surface->base.presentation_container);
+ e_presentation_time_container_feedback_merge(&sub->surface->base.presentation_container,
+ &sub->base.cached.presentation_container);
+ sub->base.cached.has_data = EINA_FALSE;
+ }
+ else
+ {
+ e_presentation_time_container_feedback_discard(&sub->surface->base.presentation_container);
+ e_presentation_time_container_feedback_merge(&sub->surface->base.presentation_container,
+ &sub->surface->base.pending.presentation_container);
+ }
+}
+
+static void
_e_subsurface_cb_request_move(struct wl_listener *listener, void *data)
{
E_Subsurface *sub;
{
EINA_SAFETY_ON_NULL_RETURN(subsurface);
wl_signal_add(&subsurface->events.cached, listener);
+}
+
+EINTERN void
+e_subsurface_sync_precommit_listener_add(E_Subsurface *subsurface, struct wl_listener *listener)
+{
+ EINA_SAFETY_ON_NULL_RETURN(subsurface);
+ wl_signal_add(&subsurface->events.sync_precommit, listener);
+}
+
+EINTERN void
+e_subsurface_desync_precommit_listener_add(E_Subsurface *subsurface, struct wl_listener *listener)
+{
+ EINA_SAFETY_ON_NULL_RETURN(subsurface);
+ wl_signal_add(&subsurface->events.desync_precommit, listener);
}
\ No newline at end of file