forked from enlightenment/efl
efl-wl: add functionality for extracting surfaces for external use
@feature
This commit is contained in:
parent
dc250e6101
commit
2d1e5da35d
|
@ -131,6 +131,18 @@ EAPI void efl_wl_minmax_set(Evas_Object *obj, Eina_Bool set);
|
|||
* @since 1.21
|
||||
*/
|
||||
EAPI void *efl_wl_global_add(Evas_Object *obj, const void *interface, uint32_t version, void *data, void *bind_cb);
|
||||
|
||||
/**
|
||||
* Extract a child surface from the compositor
|
||||
*
|
||||
* An extracted surface can be freely manipulated by external code.
|
||||
* @note size hints must be respected, and the extracted object must not be externally deleted
|
||||
*
|
||||
* @param surface The surface to extract
|
||||
* @return True if the surface was successfully extracted
|
||||
* @since 1.21
|
||||
*/
|
||||
EAPI Eina_Bool efl_wl_surface_extract(Evas_Object *surface);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -325,6 +325,7 @@ struct Comp_Surface
|
|||
Eina_Bool post_render_queue : 1;
|
||||
Eina_Bool dead : 1;
|
||||
Eina_Bool commit : 1;
|
||||
Eina_Bool extracted : 1;
|
||||
};
|
||||
|
||||
struct Comp_Subsurface
|
||||
|
@ -463,6 +464,7 @@ static inline void
|
|||
comp_surface_reparent(Comp_Surface *cs, Comp_Surface *pcs)
|
||||
{
|
||||
if (cs->parent == pcs) return;
|
||||
if (!cs->extracted)
|
||||
evas_object_smart_member_del(cs->obj);
|
||||
if (cs->parent)
|
||||
cs->parent->children = eina_inlist_remove(cs->parent->children, EINA_INLIST_GET(cs));
|
||||
|
@ -470,11 +472,13 @@ comp_surface_reparent(Comp_Surface *cs, Comp_Surface *pcs)
|
|||
{
|
||||
cs->c->surfaces = eina_inlist_remove(cs->c->surfaces, EINA_INLIST_GET(cs));
|
||||
cs->c->surfaces_count--;
|
||||
if (!cs->extracted)
|
||||
evas_object_smart_member_add(cs->obj, pcs->obj);
|
||||
pcs->children = eina_inlist_append(pcs->children, EINA_INLIST_GET(cs));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!cs->extracted)
|
||||
evas_object_smart_member_add(cs->obj, cs->c->obj);
|
||||
cs->c->surfaces = eina_inlist_append(cs->c->surfaces, EINA_INLIST_GET(cs));
|
||||
cs->c->surfaces_count++;
|
||||
|
@ -1175,6 +1179,7 @@ shell_surface_minmax_update(Comp_Surface *cs)
|
|||
|
||||
if (!cs) return;
|
||||
if (!cs->c->minmax) return;
|
||||
if (cs->extracted) return;
|
||||
evas_object_size_hint_min_get(cs->obj, &w, &h);
|
||||
evas_object_size_hint_min_set(cs->c->obj, w, h);
|
||||
evas_object_size_hint_max_get(cs->obj, &w, &h);
|
||||
|
@ -1189,6 +1194,7 @@ shell_surface_aspect_update(Comp_Surface *cs)
|
|||
|
||||
if (!cs) return;
|
||||
if (!cs->c->aspect) return;
|
||||
if (cs->extracted) return;
|
||||
evas_object_size_hint_aspect_get(cs->obj, &aspect, &w, &h);
|
||||
evas_object_size_hint_aspect_set(cs->c->obj, aspect, w, h);
|
||||
}
|
||||
|
@ -1218,6 +1224,7 @@ shell_surface_send_configure(Comp_Surface *cs)
|
|||
{
|
||||
s = wl_array_add(&states, sizeof(uint32_t));
|
||||
*s = ZXDG_TOPLEVEL_V6_STATE_ACTIVATED;
|
||||
if (!cs->extracted)
|
||||
evas_object_raise(cs->obj);
|
||||
if (cs->parent)
|
||||
cs->parent->children = eina_inlist_demote(cs->parent->children, EINA_INLIST_GET(cs));
|
||||
|
@ -1226,6 +1233,9 @@ shell_surface_send_configure(Comp_Surface *cs)
|
|||
shell_surface_activate_recurse(cs);
|
||||
}
|
||||
serial = wl_display_next_serial(cs->c->display);
|
||||
if (cs->extracted)
|
||||
evas_object_geometry_get(cs->obj, NULL, NULL, &w, &h);
|
||||
else
|
||||
evas_object_geometry_get(cs->c->clip, NULL, NULL, &w, &h);
|
||||
zxdg_toplevel_v6_send_configure(cs->role, w, h, &states);
|
||||
zxdg_surface_v6_send_configure(cs->shell.surface, serial);
|
||||
|
@ -1398,6 +1408,11 @@ comp_surface_commit_state(Comp_Surface *cs, Comp_Buffer_State *state)
|
|||
{
|
||||
evas_object_move(cs->img, x + buffer->x, y + buffer->y);
|
||||
evas_object_resize(cs->obj, buffer->w, buffer->h);
|
||||
if (cs->shell.popup)
|
||||
{
|
||||
evas_object_size_hint_min_set(cs->obj, buffer->w, buffer->h);
|
||||
evas_object_size_hint_max_set(cs->obj, buffer->w, buffer->h);
|
||||
}
|
||||
}
|
||||
else if (cs->shell.new)
|
||||
shell_surface_init(cs);
|
||||
|
@ -2349,7 +2364,7 @@ comp_surface_smart_hide(Evas_Object *obj)
|
|||
if (!evas_object_visible_get(lcs->obj)) continue;
|
||||
if ((!lcs->shell.surface) || (!lcs->role)) continue;
|
||||
lcs->shell.activated = 1;
|
||||
if (lcs->shell.popup)
|
||||
if (lcs->shell.popup && (!lcs->extracted))
|
||||
evas_object_raise(lcs->obj);
|
||||
else
|
||||
shell_surface_send_configure(lcs);
|
||||
|
@ -3071,6 +3086,7 @@ shell_surface_toplevel_set_parent(struct wl_client *client EINA_UNUSED, struct w
|
|||
if (parent_resource) pcs = wl_resource_get_user_data(parent_resource);
|
||||
|
||||
comp_surface_reparent(cs, pcs);
|
||||
evas_object_smart_callback_call(cs->c->obj, "child_added", cs->obj);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3256,6 +3272,7 @@ shell_surface_popup_create(struct wl_client *client, struct wl_resource *resourc
|
|||
comp_surface_reparent(cs, wl_resource_get_user_data(parent_resource));
|
||||
cs->shell.positioner = wl_resource_get_user_data(positioner_resource);
|
||||
_apply_positioner(cs, cs->shell.positioner);
|
||||
evas_object_smart_callback_call(cs->c->obj, "popup_added", cs->obj);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -5135,7 +5152,7 @@ comp_smart_resize(Evas_Object *obj, int w, int h)
|
|||
output_resize(c, res);
|
||||
//fprintf(stderr, "COMP %dx%d\n", w, h);
|
||||
EINA_INLIST_FOREACH(c->surfaces, cs)
|
||||
if (cs->shell.surface && cs->role)
|
||||
if (cs->shell.surface && cs->role && (!cs->extracted))
|
||||
shell_surface_send_configure(cs);
|
||||
}
|
||||
|
||||
|
@ -5457,3 +5474,58 @@ efl_wl_global_add(Evas_Object *obj, const void *interface, uint32_t version, voi
|
|||
c = evas_object_smart_data_get(obj);
|
||||
return wl_global_create(c->display, interface, version, data, bind_cb);
|
||||
}
|
||||
|
||||
static void
|
||||
extracted_focus(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Comp_Surface *cs = data;
|
||||
|
||||
if (cs->dead) return;
|
||||
if (!cs->shell.popup)
|
||||
{
|
||||
cs->shell.activated = 1;
|
||||
shell_surface_send_configure(data);
|
||||
}
|
||||
evas_object_focus_set(cs->c->obj, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
extracted_unfocus(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Comp_Surface *cs = data;
|
||||
Evas_Object *focus;
|
||||
|
||||
if (cs->dead) return;
|
||||
focus = evas_focus_get(cs->c->evas);
|
||||
if ((!focus) || (focus == cs->c->obj)) return;
|
||||
cs->shell.activated = 0;
|
||||
shell_surface_send_configure(data);
|
||||
}
|
||||
|
||||
static void
|
||||
extracted_changed(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
|
||||
{
|
||||
Comp_Surface *cs = data;
|
||||
|
||||
if (cs->dead) return;
|
||||
shell_surface_send_configure(data);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
efl_wl_surface_extract(Evas_Object *surface)
|
||||
{
|
||||
Comp_Surface *cs;
|
||||
if (!eina_streq(evas_object_type_get(surface), "comp_surface")) abort();
|
||||
cs = evas_object_smart_data_get(surface);
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(cs->extracted, EINA_FALSE);
|
||||
EINA_SAFETY_ON_TRUE_RETURN_VAL(cs->dead, EINA_FALSE);
|
||||
cs->extracted = 1;
|
||||
if (!cs->shell.popup)
|
||||
{
|
||||
evas_object_event_callback_add(cs->obj, EVAS_CALLBACK_RESIZE, extracted_changed, cs);
|
||||
evas_object_event_callback_add(cs->obj, EVAS_CALLBACK_FOCUS_OUT, extracted_unfocus, cs);
|
||||
}
|
||||
evas_object_event_callback_add(cs->obj, EVAS_CALLBACK_FOCUS_IN, extracted_focus, cs);
|
||||
evas_object_smart_member_del(surface);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue