diff --git a/CHANGELOG.md b/CHANGELOG.md index 5798fe9c5ff..779dcebe8db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ And please only add new entries to the top of this list, right below the `# Unre - On Wayland, fix polling during consecutive `EventLoop::run_return` invocations. - On Windows, fix race issue creating fullscreen windows with `WindowBuilder::with_fullscreen` - On Android, `virtual_keycode` for `KeyboardInput` events is now filled in where a suitable match is found. +- **Breaking:** Replaced `Window::with_app_id` and `Window::with_class` with `Window::with_name`. # 0.26.1 (2022-01-05) diff --git a/src/platform/unix.rs b/src/platform/unix.rs index 43c11b0051d..50d3f79f588 100644 --- a/src/platform/unix.rs +++ b/src/platform/unix.rs @@ -21,7 +21,8 @@ use crate::dpi::Size; #[cfg(feature = "x11")] use crate::platform_impl::x11::{ffi::XVisualInfo, XConnection}; use crate::platform_impl::{ - Backend, EventLoopWindowTarget as LinuxEventLoopWindowTarget, Window as LinuxWindow, + ApplicationName, Backend, EventLoopWindowTarget as LinuxEventLoopWindowTarget, + Window as LinuxWindow, }; // TODO: stupid hack so that glutin can do its work @@ -270,21 +271,34 @@ impl WindowExtUnix for Window { pub trait WindowBuilderExtUnix { #[cfg(feature = "x11")] fn with_x11_visual(self, visual_infos: *const T) -> Self; + #[cfg(feature = "x11")] fn with_x11_screen(self, screen_id: i32) -> Self; - /// Build window with `WM_CLASS` hint; defaults to the name of the binary. Only relevant on X11. - #[cfg(feature = "x11")] - fn with_class(self, class: String, instance: String) -> Self; + /// Build window with the given `general` and `instance` names. + /// + /// On Wayland, the `general` name sets an application ID, which should match the `.desktop` + /// file destributed with your program. The `instance` is `no-op` on it. + /// + /// On X11, the `general` sets general class of `WM_CLASS(STRING)`, while `instance` set the + /// instance part of it. The resulted property looks like `WM_CLASS(STRING) = "general", "instance"`. + /// + /// For details about application ID conventions, see the + /// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id) + fn with_name>(self, general: T, instance: T) -> Self; + /// Build window with override-redirect flag; defaults to false. Only relevant on X11. #[cfg(feature = "x11")] fn with_override_redirect(self, override_redirect: bool) -> Self; + /// Build window with `_NET_WM_WINDOW_TYPE` hints; defaults to `Normal`. Only relevant on X11. #[cfg(feature = "x11")] fn with_x11_window_type(self, x11_window_type: Vec) -> Self; + /// Build window with `_GTK_THEME_VARIANT` hint set to the specified value. Currently only relevant on X11. #[cfg(feature = "x11")] fn with_gtk_theme_variant(self, variant: String) -> Self; + /// Build window with resize increment hint. Only implemented on X11. /// /// ``` @@ -299,6 +313,7 @@ pub trait WindowBuilderExtUnix { /// ``` #[cfg(feature = "x11")] fn with_resize_increments>(self, increments: S) -> Self; + /// Build window with base size hint. Only implemented on X11. /// /// ``` @@ -313,14 +328,6 @@ pub trait WindowBuilderExtUnix { /// ``` #[cfg(feature = "x11")] fn with_base_size>(self, base_size: S) -> Self; - - /// Build window with a given application ID. It should match the `.desktop` file distributed with - /// your program. Only relevant on Wayland. - /// - /// For details about application ID conventions, see the - /// [Desktop Entry Spec](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#desktop-file-id) - #[cfg(feature = "wayland")] - fn with_app_id>(self, app_id: T) -> Self; } impl WindowBuilderExtUnix for WindowBuilder { @@ -342,9 +349,8 @@ impl WindowBuilderExtUnix for WindowBuilder { } #[inline] - #[cfg(feature = "x11")] - fn with_class(mut self, instance: String, class: String) -> Self { - self.platform_specific.class = Some((instance, class)); + fn with_name>(mut self, general: T, instance: T) -> Self { + self.platform_specific.name = Some(ApplicationName::new(general.into(), instance.into())); self } @@ -382,13 +388,6 @@ impl WindowBuilderExtUnix for WindowBuilder { self.platform_specific.base_size = Some(base_size.into()); self } - - #[inline] - #[cfg(feature = "wayland")] - fn with_app_id>(mut self, app_id: T) -> Self { - self.platform_specific.app_id = Some(app_id.into()); - self - } } /// Additional methods on `MonitorHandle` that are specific to Linux. diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 16f66e34b44..0e5b9c53aab 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -72,8 +72,21 @@ impl Default for PlatformSpecificEventLoopAttributes { } } +#[derive(Debug, Clone, PartialEq)] +pub struct ApplicationName { + pub general: String, + pub instance: String, +} + +impl ApplicationName { + pub fn new(general: String, instance: String) -> Self { + Self { general, instance } + } +} + #[derive(Clone)] pub struct PlatformSpecificWindowBuilderAttributes { + pub name: Option, #[cfg(feature = "x11")] pub visual_infos: Option, #[cfg(feature = "x11")] @@ -83,20 +96,17 @@ pub struct PlatformSpecificWindowBuilderAttributes { #[cfg(feature = "x11")] pub base_size: Option, #[cfg(feature = "x11")] - pub class: Option<(String, String)>, - #[cfg(feature = "x11")] pub override_redirect: bool, #[cfg(feature = "x11")] pub x11_window_types: Vec, #[cfg(feature = "x11")] pub gtk_theme_variant: Option, - #[cfg(feature = "wayland")] - pub app_id: Option, } impl Default for PlatformSpecificWindowBuilderAttributes { fn default() -> Self { Self { + name: None, #[cfg(feature = "x11")] visual_infos: None, #[cfg(feature = "x11")] @@ -106,15 +116,11 @@ impl Default for PlatformSpecificWindowBuilderAttributes { #[cfg(feature = "x11")] base_size: None, #[cfg(feature = "x11")] - class: None, - #[cfg(feature = "x11")] override_redirect: false, #[cfg(feature = "x11")] x11_window_types: vec![XWindowType::Normal], #[cfg(feature = "x11")] gtk_theme_variant: None, - #[cfg(feature = "wayland")] - app_id: None, } } } diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index fa48c573f00..a21e0e8a878 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -165,8 +165,8 @@ impl Window { window.set_max_size(max_size); // Set Wayland specific window attributes. - if let Some(app_id) = platform_attributes.app_id { - window.set_app_id(app_id); + if let Some(name) = platform_attributes.name { + window.set_app_id(name.general); } // Set common window attributes. diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index cee419afbef..6f446f177c2 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -306,11 +306,11 @@ impl UnownedWindow { // WM_CLASS must be set *before* mapping the window, as per ICCCM! { - let (class, instance) = if let Some((instance, class)) = pl_attribs.class { - let instance = CString::new(instance.as_str()) + let (class, instance) = if let Some(name) = pl_attribs.name { + let instance = CString::new(name.instance.as_str()) .expect("`WM_CLASS` instance contained null byte"); - let class = - CString::new(class.as_str()).expect("`WM_CLASS` class contained null byte"); + let class = CString::new(name.general.as_str()) + .expect("`WM_CLASS` class contained null byte"); (instance, class) } else { let class = env::args()