From cc9f1adb842aa3971664e9c4f7f220d2c17a59b1 Mon Sep 17 00:00:00 2001 From: Thomas Krause Date: Mon, 22 May 2023 21:40:04 +0200 Subject: [PATCH] Add an optional app_id field to eframe's NativeOptions for Wayland (#3007) * Add an optional app_id field to eframe's NativeOptions (#1600). This is used in the window builder to set the application ID, which is e.g. important for a proper configuration in `.desktop` files under Wayland. When no application ID is explicitly set, it defaults to the title of the window. * Only enable NativeOptions::app_id under Linux. The wayland feature is not sufficent as constraint and it won't compile e.g. under Windows. While Wayland could also be used on other Unix-Systems like FreeBSD, this would probably need some specific testing. Winit uses the following definition as "wayland_platform" and on which the required packages are available: > wayland_platform: { all(feature = "wayland", free_unix, not(wasm), not(redox)) }, * Do not use title as default application ID under Wayland. The title might be used to also communicate state (opened file, ...) to the user and this might have unforeseen consequences for the application ID. It seems to be better to use the old behavior of not setting an application ID in this case. Also add an example on how to set the application ID in the documentation. * Avoid as_deref(), which was a left-over of a previous version Co-authored-by: Emil Ernerfeldt --------- Co-authored-by: Emil Ernerfeldt --- crates/eframe/CHANGELOG.md | 1 + crates/eframe/src/epi/mod.rs | 40 +++++++++++++++++++++ crates/eframe/src/native/epi_integration.rs | 8 +++++ 3 files changed, 49 insertions(+) diff --git a/crates/eframe/CHANGELOG.md b/crates/eframe/CHANGELOG.md index 50bd5cb6..55c5a15b 100644 --- a/crates/eframe/CHANGELOG.md +++ b/crates/eframe/CHANGELOG.md @@ -8,6 +8,7 @@ NOTE: [`egui-winit`](../egui-winit/CHANGELOG.md), [`egui_glium`](../egui_glium/C #### Desktop/Native: * Add `Frame::request_screenshot` and `Frame::screenshot` to communicate to the backend that a screenshot of the current frame should be exposed by `Frame` during `App::post_rendering` ([#2676](https://github.com/emilk/egui/pull/2676)). * Add `eframe::run_simple_native` - a simple API for simple apps ([#2453](https://github.com/emilk/egui/pull/2453)). +* Add `NativeOptions::app_id` which allows to set the Wayland application ID under Linux ([#1600](https://github.com/emilk/egui/issues/1600)). * Fix bug where the eframe window is never destroyed on Linux when using `run_and_return` ([#2892](https://github.com/emilk/egui/issues/2892)) #### Web: diff --git a/crates/eframe/src/epi/mod.rs b/crates/eframe/src/epi/mod.rs index 85d5df8c..56f94338 100644 --- a/crates/eframe/src/epi/mod.rs +++ b/crates/eframe/src/epi/mod.rs @@ -383,6 +383,40 @@ pub struct NativeOptions { /// Configures wgpu instance/device/adapter/surface creation and renderloop. #[cfg(feature = "wgpu")] pub wgpu_options: egui_wgpu::WgpuConfiguration, + + /// On Wayland: Application ID for the window. + /// + /// The application ID is used in several places of the compositor, e.g. for + /// grouping windows of the same application. It is also important for + /// connecting the configuration of a `.desktop` file with the window, by + /// using the application ID as file name. This allows e.g. a proper icon + /// handling under Wayland. + /// + /// See [Waylands XDG shell documentation][xdg-shell] for more information + /// on this Wayland-specific option. + /// + /// [xdg-shell]: https://wayland.app/protocols/xdg-shell#xdg_toplevel:request:set_app_id + /// + /// # Example + /// ``` no_run + /// fn main() -> eframe::Result<()> { + /// + /// let mut options = eframe::NativeOptions::default(); + /// // Set the application ID for Wayland only on Linux + /// #[cfg(target_os = "linux")] + /// { + /// options.app_id = Some("egui-example".to_string()); + /// } + /// + /// eframe::run_simple_native("My egui App", options, move |ctx, _frame| { + /// egui::CentralPanel::default().show(ctx, |ui| { + /// ui.heading("My egui Application"); + /// }); + /// }) + /// } + /// ``` + #[cfg(all(feature = "wayland", target_os = "linux"))] + pub app_id: Option, } #[cfg(not(target_arch = "wasm32"))] @@ -397,6 +431,9 @@ impl Clone for NativeOptions { #[cfg(feature = "wgpu")] wgpu_options: self.wgpu_options.clone(), + #[cfg(all(feature = "wayland", target_os = "linux"))] + app_id: self.app_id.clone(), + ..*self } } @@ -453,6 +490,9 @@ impl Default for NativeOptions { #[cfg(feature = "wgpu")] wgpu_options: egui_wgpu::WgpuConfiguration::default(), + + #[cfg(all(feature = "wayland", target_os = "linux"))] + app_id: None, } } } diff --git a/crates/eframe/src/native/epi_integration.rs b/crates/eframe/src/native/epi_integration.rs index 73cee40f..f7e00412 100644 --- a/crates/eframe/src/native/epi_integration.rs +++ b/crates/eframe/src/native/epi_integration.rs @@ -3,6 +3,9 @@ use winit::event_loop::EventLoopWindowTarget; #[cfg(target_os = "macos")] use winit::platform::macos::WindowBuilderExtMacOS as _; +#[cfg(all(feature = "wayland", target_os = "linux"))] +use winit::platform::wayland::WindowBuilderExtWayland as _; + #[cfg(feature = "accesskit")] use egui::accesskit; use egui::NumExt as _; @@ -118,6 +121,11 @@ pub fn window_builder( .with_fullsize_content_view(true); } + #[cfg(all(feature = "wayland", target_os = "linux"))] + if let Some(app_id) = &native_options.app_id { + window_builder = window_builder.with_name(app_id, ""); + } + if let Some(min_size) = *min_window_size { window_builder = window_builder.with_min_inner_size(points_to_size(min_size)); }