From e8caf6f141298a85bd3987f1cfab06db4dba2ed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sawicz?= Date: Thu, 26 Sep 2024 13:42:37 +0000 Subject: [PATCH] feature: users can specify an app id for the wayland surface when running on the wayland platform (#3614) ## What's new? - Added the `--wayland-surface-app-id=` option for the wayland platform that, when set, will call [xdg_top_level::set_app_id](https://wayland.app/protocols/xdg-shell#xdg_toplevel:request:set_app_id) with the value `APP_ID` - Added the `--wayland-surface-title=` option for the wayland platform that, when set, will call [xdg_top_level::set_title](https://wayland.app/protocols/xdg-shell#xdg_toplevel:request:set_title) with the value `TITLE` --- src/platforms/wayland/display.cpp | 6 ++++-- src/platforms/wayland/display.h | 4 +++- src/platforms/wayland/displayclient.cpp | 10 ++++++++- src/platforms/wayland/displayclient.h | 6 +++++- src/platforms/wayland/platform.cpp | 10 +++++++-- src/platforms/wayland/platform.h | 7 ++++++- src/platforms/wayland/platform_symbols.cpp | 24 +++++++++++++++++++++- 7 files changed, 58 insertions(+), 9 deletions(-) diff --git a/src/platforms/wayland/display.cpp b/src/platforms/wayland/display.cpp index 520c17d40b2..c641054e06d 100644 --- a/src/platforms/wayland/display.cpp +++ b/src/platforms/wayland/display.cpp @@ -95,8 +95,10 @@ mgw::Display::Display( wl_display* const wl_display, std::shared_ptr<WlDisplayProvider> provider, std::shared_ptr<GLConfig> const&, - std::shared_ptr<DisplayReport> const& report) : - DisplayClient{wl_display, std::move(provider)}, + std::shared_ptr<DisplayReport> const& report, + std::optional<std::string> const& app_id, + std::optional<std::string> const& title) : + DisplayClient{wl_display, std::move(provider), app_id, title}, report{report}, shutdown_signal{::eventfd(0, EFD_CLOEXEC)}, flush_signal{::eventfd(0, EFD_SEMAPHORE)}, diff --git a/src/platforms/wayland/display.h b/src/platforms/wayland/display.h index b0c2eb58d6e..de97ceed225 100644 --- a/src/platforms/wayland/display.h +++ b/src/platforms/wayland/display.h @@ -61,7 +61,9 @@ class Display : public mir::graphics::Display, wl_display* const wl_display, std::shared_ptr<WlDisplayProvider> provider, std::shared_ptr<GLConfig> const& gl_config, - std::shared_ptr<DisplayReport> const& report); + std::shared_ptr<DisplayReport> const& report, + std::optional<std::string> const& app_id, + std::optional<std::string> const& title); ~Display(); diff --git a/src/platforms/wayland/displayclient.cpp b/src/platforms/wayland/displayclient.cpp index c8089af2a4f..4b99bb17f5c 100644 --- a/src/platforms/wayland/displayclient.cpp +++ b/src/platforms/wayland/displayclient.cpp @@ -269,6 +269,10 @@ void mgw::DisplayClient::Output::done() xdg_toplevel_add_listener(shell_toplevel, &shell_toplevel_listener, this); xdg_toplevel_set_fullscreen(shell_toplevel, output); + if (owner_->app_id) + xdg_toplevel_set_app_id(shell_toplevel, owner_->app_id.value().c_str()); + if (owner_->title) + xdg_toplevel_set_title(shell_toplevel, owner_->title.value().c_str()); wl_surface_set_buffer_scale(surface, host_scale); wl_surface_commit(surface); @@ -447,9 +451,13 @@ void mgw::DisplayClient::Output::set_next_image(std::unique_ptr<Framebuffer> con mgw::DisplayClient::DisplayClient( wl_display* display, - std::shared_ptr<WlDisplayProvider> provider) : + std::shared_ptr<WlDisplayProvider> provider, + std::optional<std::string> const& app_id, + std::optional<std::string> const& title) : display{display}, provider{std::move(provider)}, + app_id{app_id}, + title{title}, keyboard_context_{xkb_context_new(XKB_CONTEXT_NO_FLAGS)}, registry{nullptr, [](auto){}} { diff --git a/src/platforms/wayland/displayclient.h b/src/platforms/wayland/displayclient.h index d3fac57bfa1..a75b7307887 100644 --- a/src/platforms/wayland/displayclient.h +++ b/src/platforms/wayland/displayclient.h @@ -54,7 +54,9 @@ class DisplayClient public: DisplayClient( wl_display* display, - std::shared_ptr<WlDisplayProvider> provider); + std::shared_ptr<WlDisplayProvider> provider, + std::optional<std::string> const& app_id, + std::optional<std::string> const& title); virtual ~DisplayClient(); @@ -62,6 +64,8 @@ class DisplayClient wl_display* const display; std::shared_ptr<WlDisplayProvider> const provider; + std::optional<std::string> const app_id; + std::optional<std::string> const title; auto display_configuration() const -> std::unique_ptr<DisplayConfiguration>; void for_each_display_sync_group(const std::function<void(DisplaySyncGroup&)>& f); diff --git a/src/platforms/wayland/platform.cpp b/src/platforms/wayland/platform.cpp index 8f52e6e9a08..04404e115ac 100644 --- a/src/platforms/wayland/platform.cpp +++ b/src/platforms/wayland/platform.cpp @@ -68,9 +68,15 @@ auto make_initialised_egl_display(struct wl_display* wl_display) -> EGLDisplay } } -mgw::Platform::Platform(struct wl_display* const wl_display, std::shared_ptr<mg::DisplayReport> const& report) : +mgw::Platform::Platform( + struct wl_display* const wl_display, + std::shared_ptr<mg::DisplayReport> const& report, + std::optional<std::string> const& app_id, + std::optional<std::string> const& title) : wl_display{wl_display}, report{report}, + app_id{app_id}, + title{title}, provider{std::make_shared<WlDisplayProvider>(make_initialised_egl_display(wl_display))} { } @@ -79,7 +85,7 @@ mir::UniqueModulePtr<mg::Display> mgw::Platform::create_display( std::shared_ptr<DisplayConfigurationPolicy> const&, std::shared_ptr<GLConfig> const& gl_config) { - return mir::make_module_ptr<mgw::Display>(wl_display, provider, gl_config, report); + return mir::make_module_ptr<mgw::Display>(wl_display, provider, gl_config, report, app_id, title); } auto mgw::Platform::maybe_create_provider(const DisplayProvider::Tag& type_tag) -> std::shared_ptr<DisplayProvider> diff --git a/src/platforms/wayland/platform.h b/src/platforms/wayland/platform.h index 44fbf6df5ef..851bde03494 100644 --- a/src/platforms/wayland/platform.h +++ b/src/platforms/wayland/platform.h @@ -34,7 +34,10 @@ class WlDisplayProvider; class Platform : public graphics::DisplayPlatform { public: - Platform(struct wl_display* const wl_display, std::shared_ptr<DisplayReport> const& report); + Platform(struct wl_display* const wl_display, + std::shared_ptr<DisplayReport> const& report, + std::optional<std::string> const& app_id, + std::optional<std::string> const& title); ~Platform() = default; UniqueModulePtr<Display> create_display( @@ -47,6 +50,8 @@ class Platform : public graphics::DisplayPlatform struct wl_display* const wl_display; std::shared_ptr<DisplayReport> const report; + std::optional<std::string> const app_id; + std::optional<std::string> const title; std::shared_ptr<WlDisplayProvider> const provider; }; diff --git a/src/platforms/wayland/platform_symbols.cpp b/src/platforms/wayland/platform_symbols.cpp index 7d94ff113a2..e638fc81fb2 100644 --- a/src/platforms/wayland/platform_symbols.cpp +++ b/src/platforms/wayland/platform_symbols.cpp @@ -39,6 +39,12 @@ mir::ModuleProperties const description = { MIR_VERSION_MICRO, mir::libname() }; + +const char* const wayland_surface_app_id_option{"wayland-surface-app-id"}; +const char* const wayland_surface_app_id_option_description{"Defines the XdgToplevel app id on the surface created by the wayland platform"}; + +const char* const wayland_surface_title_option{"wayland-surface-title"}; +const char* const wayland_surface_title_option_description{"Defines the XdgTopLevel title on the surface created by the wayland platform"}; } mir::UniqueModulePtr<mg::DisplayPlatform> create_display_platform( @@ -48,14 +54,30 @@ mir::UniqueModulePtr<mg::DisplayPlatform> create_display_platform( std::shared_ptr<mir::ConsoleServices> const& /*console*/, std::shared_ptr<mg::DisplayReport> const& report) { + std::optional<std::string> app_id; + if (options->is_set(wayland_surface_app_id_option)) + app_id = options->get<std::string>(wayland_surface_app_id_option); + + std::optional<std::string> title; + if (options->is_set(wayland_surface_title_option)) + title = options->get<std::string>(wayland_surface_title_option); + mir::assert_entry_point_signature<mg::CreateDisplayPlatform>(&create_display_platform); - return mir::make_module_ptr<mgw::Platform>(mpw::connection(*options), report); + return mir::make_module_ptr<mgw::Platform>(mpw::connection(*options), report, app_id, title); } void add_graphics_platform_options(boost::program_options::options_description& config) { mir::assert_entry_point_signature<mg::AddPlatformOptions>(&add_graphics_platform_options); mpw::add_connection_options(config); + config.add_options() + (wayland_surface_app_id_option, + boost::program_options::value<std::string>(), + wayland_surface_app_id_option_description); + config.add_options() + (wayland_surface_title_option, + boost::program_options::value<std::string>(), + wayland_surface_title_option_description); } auto probe_graphics_platform(