static Eina_Bool _e_comp_wl_subsurface_synchronized_get(E_Comp_Wl_Subsurf_Data *sdata);
static void _e_comp_wl_subsurface_synchronized_commit(E_Client *ec);
static void _e_comp_wl_subsurface_remove_from_parent(E_Client *parent, E_Client *subc);
+static void _e_comp_wl_subsurface_stack_update(E_Client *ec);
+static Eina_Bool _e_comp_wl_subsurface_empty_check(E_Client *ec);
+
+static void _e_comp_wl_subsurface_cb_evas_restack(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void
_e_comp_wl_subsurface_restack_bg_rectangle(E_Client *ec)
if (!ec || !ec->comp_data || e_object_is_del(E_OBJECT(ec))) return;
+ ec->comp_data->sub.restacking = EINA_TRUE;
+
temp = ec;
EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
{
if (!subc || !subc->comp_data || e_object_is_del(E_OBJECT(subc))) continue;
- subc->comp_data->sub.restacking = EINA_TRUE;
e_client_stack_above(subc, temp);
- subc->comp_data->sub.restacking = EINA_FALSE;
temp = subc;
}
EINA_LIST_REVERSE_FOREACH(ec->comp_data->sub.below_list, l, subc)
{
if (!subc || !subc->comp_data || e_object_is_del(E_OBJECT(subc))) continue;
- subc->comp_data->sub.restacking = EINA_TRUE;
e_client_stack_below(subc, temp);
- subc->comp_data->sub.restacking = EINA_FALSE;
temp = subc;
}
EINA_LIST_REVERSE_FOREACH(ec->comp_data->sub.below_list, l, subc)
_e_comp_wl_subsurface_restack(subc);
+
+ ec->comp_data->sub.restacking = EINA_FALSE;
}
static void
ec->comp_data->sub.below_list = NULL;
_e_comp_wl_surface_sub_list_free(ec->comp_data->sub.below_list_pending);
ec->comp_data->sub.below_list_pending = NULL;
+
+ evas_object_event_callback_del(ec->frame,
+ EVAS_CALLBACK_RESTACK,
+ _e_comp_wl_subsurface_cb_evas_restack);
}
static void
{
E_Layer layer = e_client_layer_get(epc);
if (layer > E_LAYER_BOTTOM) e_client_layer_set(ec, layer);
+
+ if ((!_e_comp_wl_subsurface_data_get(epc)) &&
+ (_e_comp_wl_subsurface_empty_check(epc)))
+ {
+ /* Add a callback function for restacking of topmost. */
+ evas_object_event_callback_add(epc->frame,
+ EVAS_CALLBACK_RESTACK,
+ _e_comp_wl_subsurface_cb_evas_restack,
+ epc);
+ }
}
if (epc->comp_data)
* It's not for subsurface. */
E_FREE_FUNC(ec->comp_data->sub.below_obj, evas_object_del);
+ /* Delete a listener for restack of evas.
+ * There is no need to watch restack of evas for sub-surface because
+ * stacking for sub-surface is happened only by client, not compositor. */
+ evas_object_event_callback_del(ec->frame,
+ EVAS_CALLBACK_RESTACK,
+ _e_comp_wl_subsurface_cb_evas_restack);
+
e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_CREATE, ec);
return EINA_TRUE;
EINTERN void
e_comp_wl_subsurface_restack(E_Client *ec)
{
- EINA_SAFETY_ON_NULL_RETURN(ec);
-
- _e_comp_wl_subsurface_restack(ec);
-}
-
-E_API void
-e_comp_wl_subsurface_stack_update(E_Client *ec)
-{
E_Client *topmost;
EINA_SAFETY_ON_NULL_RETURN(ec);
- if (!ec->comp_data) return;
- if (e_object_is_del(E_OBJECT(ec))) return;
- if (ec->comp_data->sub.restacking) return;
-
- /* return if ec isn't both a parent of a subsurface and a subsurface itself */
- if (!ec->comp_data->sub.list && !ec->comp_data->sub.below_list && !ec->comp_data->sub.data)
+ topmost = e_comp_wl_topmost_parent_get(ec);
+ if (topmost != ec)
{
- if (ec->comp_data->sub.below_obj)
- _e_comp_wl_subsurface_restack_bg_rectangle(ec);
+ ELOGF("SUB-COMP",
+ "WARN: This API is only for topmost parent, not sub-surface.",
+ ec);
return;
}
- topmost = e_comp_wl_topmost_parent_get(ec);
-
- _e_comp_wl_subsurface_restack(topmost);
- _e_comp_wl_subsurface_restack_bg_rectangle(topmost);
-
- //To update client stack list
- if ((ec->comp_data->sub.data) &&
- (ec->comp_data->sub.data->parent))
- {
- E_Client *parent;
- Evas_Object *o;
+ _e_comp_wl_subsurface_restack(ec);
+}
- parent = ec->comp_data->sub.data->parent;
+E_API void
+e_comp_wl_subsurface_stack_update(E_Client *ec)
+{
+ EINA_SAFETY_ON_NULL_RETURN(ec);
- if ((parent->comp_data->sub.list) &&
- (eina_list_data_find(parent->comp_data->sub.list, ec)))
- {
- //stack above done
- o = evas_object_below_get(ec->frame);
- e_comp_object_layer_update(ec->frame, o, NULL);
- }
- else if ((parent->comp_data->sub.below_list) &&
- (eina_list_data_find(parent->comp_data->sub.below_list, ec)))
- {
- //stack below done
- o = evas_object_above_get(ec->frame);
- e_comp_object_layer_update(ec->frame, NULL, o);
- }
- }
+ _e_comp_wl_subsurface_stack_update(ec);
}
EINTERN Eina_Bool
eina_list_remove(parent->comp_data->sub.below_list, subc);
parent->comp_data->sub.below_list_pending =
eina_list_remove(parent->comp_data->sub.below_list_pending, subc);
+
+ if ((!_e_comp_wl_subsurface_data_get(parent)) &&
+ (_e_comp_wl_subsurface_empty_check(parent)))
+ {
+ /* No need to watch restack of evas since this surface doesn't have
+ * sub-surface anymore. */
+ evas_object_event_callback_del(parent->frame,
+ EVAS_CALLBACK_RESTACK,
+ _e_comp_wl_subsurface_cb_evas_restack);
+ }
+
+
}
static E_Comp_Wl_Subsurf_Data *
{
return (ec->comp_data) ? (ec->comp_data->sub.data) : NULL;
}
+
+static void
+_e_comp_wl_subsurface_stack_update(E_Client *ec)
+{
+ E_Client *topmost;
+
+ if (!ec->comp_data) return;
+ if (e_object_is_del(E_OBJECT(ec))) return;
+ if (ec->comp_data->sub.restacking) return;
+
+ /* return if ec isn't both a parent of a subsurface and a subsurface itself */
+ if (!ec->comp_data->sub.list && !ec->comp_data->sub.below_list && !ec->comp_data->sub.data)
+ {
+ if (ec->comp_data->sub.below_obj)
+ _e_comp_wl_subsurface_restack_bg_rectangle(ec);
+ return;
+ }
+
+ topmost = e_comp_wl_topmost_parent_get(ec);
+
+ _e_comp_wl_subsurface_restack(topmost);
+ _e_comp_wl_subsurface_restack_bg_rectangle(topmost);
+
+ //To update client stack list
+ if ((ec->comp_data->sub.data) &&
+ (ec->comp_data->sub.data->parent))
+ {
+ E_Client *parent;
+ Evas_Object *o;
+
+ parent = ec->comp_data->sub.data->parent;
+
+ if ((parent->comp_data->sub.list) &&
+ (eina_list_data_find(parent->comp_data->sub.list, ec)))
+ {
+ //stack above done
+ o = evas_object_below_get(ec->frame);
+ e_comp_object_layer_update(ec->frame, o, NULL);
+ }
+ else if ((parent->comp_data->sub.below_list) &&
+ (eina_list_data_find(parent->comp_data->sub.below_list, ec)))
+ {
+ //stack below done
+ o = evas_object_above_get(ec->frame);
+ e_comp_object_layer_update(ec->frame, NULL, o);
+ }
+ }
+}
+
+static void
+_e_comp_wl_subsurface_cb_evas_restack(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ E_Client *topmost;
+
+ /* Given data must be a topmost E_Client of subsurfaces. */
+ topmost = data;
+ if (topmost->comp_data->sub.restacking)
+ {
+ ELOGF("SUB-COMP", "A topmost parent is getting restacked", topmost);
+ return;
+ }
+
+ _e_comp_wl_subsurface_stack_update(topmost);
+}
+
+
+static Eina_Bool
+_e_comp_wl_subsurface_empty_check(E_Client *ec)
+{
+ return (!ec->comp_data) ||
+ ((eina_list_count(ec->comp_data->sub.list) == 0) &&
+ (eina_list_count(ec->comp_data->sub.list_pending) == 0) &&
+ (eina_list_count(ec->comp_data->sub.below_list) == 0) &&
+ (eina_list_count(ec->comp_data->sub.below_list_pending) == 0));
+}