diff --git a/platform/wayland/cog-platform-wl.c b/platform/wayland/cog-platform-wl.c index 246e7ae7..ba047e00 100644 --- a/platform/wayland/cog-platform-wl.c +++ b/platform/wayland/cog-platform-wl.c @@ -212,6 +212,10 @@ registry_on_global(void *data, struct wl_registry *registry, uint32_t name, cons } else if (strcmp(interface, weston_content_protection_interface.name) == 0) { display->protection = wl_registry_bind(registry, name, &weston_content_protection_interface, 1); #endif /* COG_ENABLE_WESTON_CONTENT_PROTECTION */ +#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1 + } else if (strcmp(interface, zxdg_decoration_manager_v1_interface.name) == 0) { + display->xdg_decoration = wl_registry_bind(registry, name, &zxdg_decoration_manager_v1_interface, 1); +#endif /* COG_HAVE_XDG_DECORATION_UNSTABLE_V1 */ } else if (strcmp(interface, wl_output_interface.name) == 0) { /* Version 2 introduced the wl_output_listener::scale. */ CogWlOutput *item = g_new0(CogWlOutput, 1); @@ -1181,6 +1185,10 @@ init_wayland(CogWlPlatform *platform, GError **error) static void clear_wayland(CogWlPlatform *platform) { +#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1 + g_clear_pointer(&platform->display->xdg_decoration, zxdg_decoration_manager_v1_destroy); +#endif /* COG_HAVE_XDG_DECORATION_UNSTABLE_V1 */ + cog_wl_display_destroy(platform->display); } diff --git a/platform/wayland/cog-utils-wl.h b/platform/wayland/cog-utils-wl.h index 1adb6a15..c4d1f519 100644 --- a/platform/wayland/cog-utils-wl.h +++ b/platform/wayland/cog-utils-wl.h @@ -15,6 +15,10 @@ # include "cog-xdp-parent-wl.h" #endif +#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1 +# include "xdg-decoration-unstable-v1-client.h" +#endif + #include #include #include @@ -116,6 +120,10 @@ struct _CogWlWindow { struct xdg_toplevel *xdg_toplevel; struct wl_shell_surface *shell_surface; +#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1 + struct zxdg_toplevel_decoration_v1 *xdg_decoration; +#endif /* COG_HAVE_XDG_DECORATION_UNSTABLE_V1 */ + #if COG_HAVE_LIBPORTAL struct xdp_parent_wl_data xdp_parent_wl_data; #endif /* COG_HAVE_LIBPORTAL */ @@ -231,6 +239,10 @@ struct _CogWlDisplay { struct zwp_fullscreen_shell_v1 *fshell; struct wl_shell *shell; +#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1 + struct zxdg_decoration_manager_v1 *xdg_decoration; +#endif + CogWlSeat *seat_default; struct wl_list seats; /* wl_list */ diff --git a/platform/wayland/cog-viewport-wl.c b/platform/wayland/cog-viewport-wl.c index fab316d3..7221fea9 100644 --- a/platform/wayland/cog-viewport-wl.c +++ b/platform/wayland/cog-viewport-wl.c @@ -16,6 +16,10 @@ #include "fullscreen-shell-unstable-v1-client.h" #include "xdg-shell-client.h" +#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1 +# include "xdg-decoration-unstable-v1-client.h" +#endif + G_DEFINE_DYNAMIC_TYPE(CogWlViewport, cog_wl_viewport, COG_TYPE_VIEWPORT) static void cog_wl_viewport_dispose(GObject *); @@ -41,6 +45,10 @@ destroy_video_surface(gpointer data) static void destroy_window(CogWlViewport *viewport) { +#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1 + g_clear_pointer(&viewport->window.xdg_decoration, zxdg_toplevel_decoration_v1_destroy); +#endif + g_clear_pointer(&viewport->window.xdg_toplevel, xdg_toplevel_destroy); g_clear_pointer(&viewport->window.xdg_surface, xdg_surface_destroy); g_clear_pointer(&viewport->window.shell_surface, wl_shell_surface_destroy); @@ -265,6 +273,19 @@ cog_wl_viewport_create_window(CogWlViewport *viewport, GError **error) viewport->window.xdg_toplevel = xdg_surface_get_toplevel(viewport->window.xdg_surface); g_assert(viewport->window.xdg_toplevel); +#if COG_HAVE_XDG_DECORATION_UNSTABLE_V1 + /* + * Ask the compositor for server-side decorations. The compositor may + * still prefer client-side decorations, but do not attach a listener + * because knowing the compositor's preference is pointless because + * there is no support for painting client-side decorations. + */ + viewport->window.xdg_decoration = + zxdg_decoration_manager_v1_get_toplevel_decoration(display->xdg_decoration, viewport->window.xdg_toplevel); + zxdg_toplevel_decoration_v1_set_mode(viewport->window.xdg_decoration, + ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); +#endif /* COG_HAVE_XDG_DECORATION_UNSTABLE_V1 */ + xdg_toplevel_add_listener(viewport->window.xdg_toplevel, &xdg_toplevel_listener, viewport); xdg_toplevel_set_title(viewport->window.xdg_toplevel, COG_DEFAULT_APPNAME); diff --git a/platform/wayland/meson.build b/platform/wayland/meson.build index c52a6fa7..74215f0a 100644 --- a/platform/wayland/meson.build +++ b/platform/wayland/meson.build @@ -38,6 +38,7 @@ wayland_platform_protocols = { ['text-input', 1], ['text-input', 3], ['xdg-foreign', 2], + ['xdg-decoration', 1, 'optional'], ], 'weston': wayland_platform_weston_protocols, } @@ -78,22 +79,34 @@ fs = import('fs') wayland_platform_sources = [] foreach kind, proto_list : wayland_platform_protocols foreach item : proto_list + proto_optional = false if kind == 'stable' proto_name = item proto_dir = join_paths(wayland_protocols_path, 'stable', item) elif kind == 'unstable' or kind == 'staging' proto_name = '@0@-@1@-v@2@'.format(item[0], kind, item[1]) proto_dir = join_paths(wayland_protocols_path, 'unstable', item[0]) + proto_optional = item.length() == 3 and item[2] == 'optional' elif kind == 'weston' proto_name = item proto_dir = weston_protocols_path else error('Unknown Wayland protocol type: @0@'.format(kind)) endif + proto_macro = proto_name.underscorify().to_upper() xml_path = join_paths(proto_dir, '@0@.xml'.format(proto_name)) if not fs.is_file(xml_path) - error('Cannot find protocol @0@, file does not exist: @1@'.format(proto_name, xml_path)) + if proto_optional + wayland_platform_c_args += ['-DHAVE_@0@=0'.format(proto_macro)] + continue + else + error('Cannot find protocol @0@, file does not exist: @1@'.format(proto_name, xml_path)) + endif + endif + + if proto_optional + wayland_platform_c_args += ['-DCOG_HAVE_@0@=1'.format(proto_macro)] endif wayland_platform_sources += [custom_target(