diff --git a/src/Makefile_Ecore_Wl2.am b/src/Makefile_Ecore_Wl2.am index 7f3eb2f007..0047c36bc3 100644 --- a/src/Makefile_Ecore_Wl2.am +++ b/src/Makefile_Ecore_Wl2.am @@ -33,7 +33,9 @@ lib/ecore_wl2/linux-dmabuf-unstable-v1-client-protocol.h \ lib/ecore_wl2/xdg-shell-unstable-v6-client-protocol.h \ lib/ecore_wl2/xdg-shell-unstable-v6-protocol.c \ lib/ecore_wl2/text-input-unstable-v1-client-protocol.h \ -lib/ecore_wl2/text-input-unstable-v1-protocol.c +lib/ecore_wl2/text-input-unstable-v1-protocol.c \ +lib/ecore_wl2/efl-hints-client-protocol.h \ +lib/ecore_wl2/efl-hints-protocol.c lib_ecore_wl2_libecore_wl2_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @ECORE_WL2_CFLAGS@ lib_ecore_wl2_libecore_wl2_la_LIBADD = @ECORE_WL2_LIBS@ @@ -56,6 +58,8 @@ lib/ecore_wl2/efl-aux-hints-client-protocol.h \ lib/ecore_wl2/session-recovery-protocol.c \ lib/ecore_wl2/session-recovery-client-protocol.h \ lib/ecore_wl2/text-input-unstable-v1-client-protocol.h \ - lib/ecore_wl2/text-input-unstable-v1-protocol.c + lib/ecore_wl2/text-input-unstable-v1-protocol.c \ +lib/ecore_wl2/efl-hints-client-protocol.h \ +lib/ecore_wl2/efl-hints-protocol.c endif diff --git a/src/Makefile_Wayland_Protocols.am b/src/Makefile_Wayland_Protocols.am index b96cce9ac4..1bbfe20e77 100644 --- a/src/Makefile_Wayland_Protocols.am +++ b/src/Makefile_Wayland_Protocols.am @@ -1,5 +1,6 @@ EXTRA_DIST2 += \ wayland_protocol/efl-aux-hints.xml \ +wayland_protocol/efl-hints.xml \ wayland_protocol/session-recovery.xml \ wayland_protocol/teamwork.xml \ wayland_protocol/www.xml diff --git a/src/Makefile_efl_wl.am b/src/Makefile_efl_wl.am index aae58ff780..ac3c00db69 100644 --- a/src/Makefile_efl_wl.am +++ b/src/Makefile_efl_wl.am @@ -15,7 +15,9 @@ nodist_lib_efl_wl_libefl_wl_la_SOURCES = \ lib/efl_wl/linux-dmabuf-unstable-v1-protocol.c \ lib/efl_wl/linux-dmabuf-unstable-v1-server-protocol.h \ lib/efl_wl/xdg-shell-unstable-v6-protocol.c \ -lib/efl_wl/xdg-shell-unstable-v6-server-protocol.h +lib/efl_wl/xdg-shell-unstable-v6-server-protocol.h \ +lib/efl_wl/efl-hints-protocol.c \ +lib/efl_wl/efl-hints-server-protocol.h lib_efl_wl_libefl_wl_la_CPPFLAGS = -I$(top_builddir)/lib/efl @EFL_WL_CFLAGS@ lib_efl_wl_libefl_wl_la_LIBADD = @EFL_WL_LIBS@ diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index 81084e1975..eab1bfe3e7 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -736,6 +736,13 @@ EAPI struct wl_surface *ecore_wl2_window_surface_get(Ecore_Wl2_Window *window); */ EAPI int ecore_wl2_window_surface_id_get(Ecore_Wl2_Window *window); +/** + * @see evas_object_size_hint_aspect_set + * @ingroup Ecore_Wl2_Window_Group + * @since 1.21 + */ +EAPI void ecore_wl2_window_aspect_set(Ecore_Wl2_Window *window, int w, int h, unsigned int aspect); + /** * Show a given Ecore_Wl2_Window * diff --git a/src/lib/ecore_wl2/ecore_wl2_display.c b/src/lib/ecore_wl2/ecore_wl2_display.c index 48c62e5545..63c79f9d07 100644 --- a/src/lib/ecore_wl2/ecore_wl2_display.c +++ b/src/lib/ecore_wl2/ecore_wl2_display.c @@ -5,6 +5,7 @@ #include "ecore_wl2_private.h" #include "linux-dmabuf-unstable-v1-client-protocol.h" +#include "efl-hints-client-protocol.h" static Eina_Hash *_server_displays = NULL; static Eina_Hash *_client_displays = NULL; @@ -336,6 +337,16 @@ _cb_global_add(void *data, struct wl_registry *registry, unsigned int id, const _ecore_wl2_output_add(ewd, id); else if (!strcmp(interface, "wl_seat")) _ecore_wl2_input_add(ewd, id, version); + else if (!strcmp(interface, "efl_hints")) + { + Ecore_Wl2_Window *window; + + ewd->wl.efl_hints = wl_registry_bind(registry, id, &efl_hints_interface, 1); + EINA_INLIST_FOREACH(ewd->windows, window) + if (window->zxdg_toplevel && window->aspect.set) + efl_hints_set_aspect(window->display->wl.efl_hints, window->zxdg_toplevel, + window->aspect.w, window->aspect.h, window->aspect.aspect); + } event: /* allocate space for event structure */ @@ -437,6 +448,7 @@ _ecore_wl2_display_globals_cleanup(Ecore_Wl2_Display *ewd) if (ewd->wl.subcompositor) wl_subcompositor_destroy(ewd->wl.subcompositor); if (ewd->wl.dmabuf) zwp_linux_dmabuf_v1_destroy(ewd->wl.dmabuf); if (ewd->wl.efl_aux_hints) efl_aux_hints_destroy(ewd->wl.efl_aux_hints); + if (ewd->wl.efl_hints) efl_hints_destroy(ewd->wl.efl_hints); if (ewd->wl.registry) wl_registry_destroy(ewd->wl.registry); } diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h index 3569db9f39..e857bbdec4 100644 --- a/src/lib/ecore_wl2/ecore_wl2_private.h +++ b/src/lib/ecore_wl2/ecore_wl2_private.h @@ -96,6 +96,7 @@ struct _Ecore_Wl2_Display struct zwp_e_session_recovery *session_recovery; struct efl_aux_hints *efl_aux_hints; struct zwp_teamwork *teamwork; + struct efl_hints *efl_hints; int compositor_version; } wl; @@ -180,6 +181,13 @@ struct _Ecore_Wl2_Window Ecore_Wl2_Window_Type type; + struct + { + int w, h; + unsigned int aspect; + Eina_Bool set : 1; + } aspect; + Eina_Inlist *subsurfs; Eina_List *supported_aux_hints; diff --git a/src/lib/ecore_wl2/ecore_wl2_window.c b/src/lib/ecore_wl2/ecore_wl2_window.c index 78f6129af0..bb5196f474 100644 --- a/src/lib/ecore_wl2/ecore_wl2_window.c +++ b/src/lib/ecore_wl2/ecore_wl2_window.c @@ -3,6 +3,7 @@ #endif #include "ecore_wl2_private.h" +#include "efl-hints-client-protocol.h" void _ecore_wl2_window_semi_free(Ecore_Wl2_Window *window) @@ -472,6 +473,9 @@ _ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window *window) if (window->fullscreen) zxdg_toplevel_v6_set_fullscreen(window->zxdg_toplevel, NULL); + if (window->aspect.set && window->display->wl.efl_hints) + efl_hints_set_aspect(window->display->wl.efl_hints, window->zxdg_toplevel, + window->aspect.w, window->aspect.h, window->aspect.aspect); wl_surface_commit(window->surface); } @@ -1535,3 +1539,20 @@ ecore_wl2_window_floating_mode_get(Ecore_Wl2_Window *window) EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE); return window->floating; } + +EAPI void +ecore_wl2_window_aspect_set(Ecore_Wl2_Window *window, int w, int h, unsigned int aspect) +{ + EINA_SAFETY_ON_NULL_RETURN(window); + EINA_SAFETY_ON_TRUE_RETURN(w < 1); + EINA_SAFETY_ON_TRUE_RETURN(h < 1); + if ((window->aspect.aspect == aspect) && + (window->aspect.w == w) && + (window->aspect.h == h)) return; + window->aspect.w = w; + window->aspect.h = h; + window->aspect.aspect = aspect; + window->aspect.set = 1; + if (window->display->wl.efl_hints && window->zxdg_toplevel) + efl_hints_set_aspect(window->display->wl.efl_hints, window->zxdg_toplevel, w, h, aspect); +} diff --git a/src/lib/efl_wl/Efl_Wl.h b/src/lib/efl_wl/Efl_Wl.h index 2de79e2e96..51bcc43832 100644 --- a/src/lib/efl_wl/Efl_Wl.h +++ b/src/lib/efl_wl/Efl_Wl.h @@ -106,6 +106,14 @@ EAPI void efl_wl_rotate(Evas_Object *obj, Efl_Wl_Rotation rot, Eina_Bool rtl); * @param scale The scale factor to set */ EAPI void efl_wl_scale_set(Evas_Object *obj, double scale); + +/** + * Transfer aspect hints from top-most surface onto the efl_wl object + * + * @param obj The compositor widget + * @param set Whether to enable aspect setting + */ +EAPI void efl_wl_aspect_set(Evas_Object *obj, Eina_Bool set); #endif #endif diff --git a/src/lib/efl_wl/efl_wl.c b/src/lib/efl_wl/efl_wl.c index 03e1128836..2a78282372 100644 --- a/src/lib/efl_wl/efl_wl.c +++ b/src/lib/efl_wl/efl_wl.c @@ -16,6 +16,7 @@ #include #include "xdg-shell-unstable-v6-server-protocol.h" +#include "efl-hints-server-protocol.h" #include "dmabuf.h" #include "Ecore_Evas.h" @@ -142,6 +143,7 @@ typedef struct Comp Eina_Bool data_device_proxy : 1; Eina_Bool x11_selection : 1; Eina_Bool rtl : 1; + Eina_Bool aspect : 1; } Comp; typedef struct Comp_Data_Device_Source Comp_Data_Device_Source; @@ -1165,6 +1167,18 @@ shell_surface_activate_recurse(Comp_Surface *cs) eina_list_free(parents); } +static void +shell_surface_aspect_update(Comp_Surface *cs) +{ + Evas_Aspect_Control aspect; + int w, h; + + if (!cs) return; + if (!cs->c->aspect) return; + evas_object_size_hint_aspect_get(cs->obj, &aspect, &w, &h); + evas_object_size_hint_aspect_set(cs->c->obj, aspect, w, h); +} + static void shell_surface_send_configure(Comp_Surface *cs) { @@ -1210,6 +1224,7 @@ shell_surface_send_configure(Comp_Surface *cs) EINA_INLIST_FOREACH(cs->children, ccs) if (ccs->shell.surface && ccs->role && ccs->shell.popup) ccs->shell.activated = cs->shell.activated; + shell_surface_aspect_update(cs); } else shell_surface_deactivate_recurse(cs); @@ -4894,6 +4909,32 @@ EFL_CALLBACKS_ARRAY_DEFINE(comp_device_cbs, { EFL_CANVAS_EVENT_DEVICE_ADDED, comp_device_add }, { EFL_CANVAS_EVENT_DEVICE_REMOVED, comp_device_del }); +static void +hints_set_aspect(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface, uint32_t width, uint32_t height, uint32_t aspect) +{ + Comp_Surface *cs = wl_resource_get_user_data(surface); + evas_object_size_hint_aspect_set(cs->obj, aspect, width, height); + if (cs == cs->c->active_surface) + shell_surface_aspect_update(cs); +} + +static const struct efl_hints_interface hints_interface = +{ + hints_set_aspect, +}; + +static void +efl_hints_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) +{ + struct wl_resource *res; + + if (!client_allowed_check(data, client)) return; + res = wl_resource_create(client, &efl_hints_interface, version, id); + wl_resource_set_implementation(res, &hints_interface, data, NULL); +} + + + static void comp_smart_add(Evas_Object *obj) { @@ -4930,6 +4971,7 @@ comp_smart_add(Evas_Object *obj) wl_global_create(c->display, &wl_output_interface, 2, c, output_bind); wl_global_create(c->display, &zxdg_shell_v6_interface, 1, c, shell_bind); wl_global_create(c->display, &wl_data_device_manager_interface, 3, c, data_device_manager_bind); + wl_global_create(c->display, &efl_hints_interface, 1, c, efl_hints_bind); wl_display_init_shm(c->display); if (env) @@ -5317,3 +5359,17 @@ efl_wl_scale_set(Evas_Object *obj, double scale) if (wl_resource_get_version(res) >= WL_OUTPUT_SCALE_SINCE_VERSION) wl_output_send_scale(res, lround(c->scale)); } + +void +efl_wl_aspect_set(Evas_Object *obj, Eina_Bool set) +{ + Comp *c; + + if (!eina_streq(evas_object_type_get(obj), "comp")) abort(); + c = evas_object_smart_data_get(obj); + c->aspect = !!set; + if (c->aspect) + shell_surface_aspect_update(c->active_surface); + else + evas_object_size_hint_aspect_set(obj, EVAS_ASPECT_CONTROL_NONE, 0, 0); +} diff --git a/src/wayland_protocol/efl-hints.xml b/src/wayland_protocol/efl-hints.xml new file mode 100644 index 0000000000..51689d780c --- /dev/null +++ b/src/wayland_protocol/efl-hints.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + +