diff --git a/crates/collab_ui/src/collab_ui.rs b/crates/collab_ui/src/collab_ui.rs index ad5e25198f..e5f139b887 100644 --- a/crates/collab_ui/src/collab_ui.rs +++ b/crates/collab_ui/src/collab_ui.rs @@ -122,5 +122,6 @@ fn notification_window_options( display_id: Some(screen.id()), fullscreen: false, window_background: WindowBackgroundAppearance::default(), + app_id: Some("dev.zed.Zed".to_owned()), } } diff --git a/crates/gpui/examples/window_positioning.rs b/crates/gpui/examples/window_positioning.rs index ef00f88a7b..aa70236e3c 100644 --- a/crates/gpui/examples/window_positioning.rs +++ b/crates/gpui/examples/window_positioning.rs @@ -54,6 +54,7 @@ fn main() { kind: WindowKind::PopUp, is_movable: false, fullscreen: false, + app_id: None, } }; diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 2b3b901ebf..074f7fda93 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -209,6 +209,7 @@ pub(crate) trait PlatformWindow: HasWindowHandle + HasDisplayHandle { fn activate(&self); fn is_active(&self) -> bool; fn set_title(&mut self, title: &str); + fn set_app_id(&mut self, app_id: &str); fn set_background_appearance(&mut self, background_appearance: WindowBackgroundAppearance); fn set_edited(&mut self, edited: bool); fn show_character_palette(&self); @@ -557,6 +558,9 @@ pub struct WindowOptions { /// The appearance of the window background. pub window_background: WindowBackgroundAppearance, + + /// Application identifier of the window. Can by used by desktop environments to group applications together. + pub app_id: Option, } /// The variables that can be configured when creating a new window @@ -599,6 +603,7 @@ impl Default for WindowOptions { display_id: None, fullscreen: false, window_background: WindowBackgroundAppearance::default(), + app_id: None, } } } diff --git a/crates/gpui/src/platform/linux/wayland/window.rs b/crates/gpui/src/platform/linux/wayland/window.rs index 82bfa6c0a8..17ee15306c 100644 --- a/crates/gpui/src/platform/linux/wayland/window.rs +++ b/crates/gpui/src/platform/linux/wayland/window.rs @@ -609,6 +609,10 @@ impl PlatformWindow for WaylandWindow { self.borrow_mut().toplevel.set_title(title.to_string()); } + fn set_app_id(&mut self, app_id: &str) { + self.borrow_mut().toplevel.set_app_id(app_id.to_owned()); + } + fn set_background_appearance(&mut self, _background_appearance: WindowBackgroundAppearance) { // todo(linux) } diff --git a/crates/gpui/src/platform/linux/x11/window.rs b/crates/gpui/src/platform/linux/x11/window.rs index 5bbedffe17..da0f6d2a58 100644 --- a/crates/gpui/src/platform/linux/x11/window.rs +++ b/crates/gpui/src/platform/linux/x11/window.rs @@ -494,6 +494,21 @@ impl PlatformWindow for X11Window { .unwrap(); } + fn set_app_id(&mut self, app_id: &str) { + let mut data = Vec::with_capacity(app_id.len() * 2 + 1); + data.extend(app_id.bytes()); // instance https://unix.stackexchange.com/a/494170 + data.push(b'\0'); + data.extend(app_id.bytes()); // class + + self.0.xcb_connection.change_property8( + xproto::PropMode::REPLACE, + self.0.x_window, + xproto::AtomEnum::WM_CLASS, + xproto::AtomEnum::STRING, + &data, + ); + } + // todo(linux) fn set_edited(&mut self, edited: bool) {} diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 340ef6a45b..86d01ba2dc 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -982,6 +982,8 @@ impl PlatformWindow for MacWindow { } } + fn set_app_id(&mut self, _app_id: &str) {} + fn set_background_appearance(&mut self, background_appearance: WindowBackgroundAppearance) { let this = self.0.as_ref().lock(); let blur_radius = if background_appearance == WindowBackgroundAppearance::Blurred { diff --git a/crates/gpui/src/platform/test/window.rs b/crates/gpui/src/platform/test/window.rs index 14c72251a3..959d72d9fa 100644 --- a/crates/gpui/src/platform/test/window.rs +++ b/crates/gpui/src/platform/test/window.rs @@ -190,6 +190,8 @@ impl PlatformWindow for TestWindow { self.0.lock().title = Some(title.to_owned()); } + fn set_app_id(&mut self, _app_id: &str) {} + fn set_background_appearance(&mut self, _background: WindowBackgroundAppearance) { unimplemented!() } diff --git a/crates/gpui/src/platform/windows/window.rs b/crates/gpui/src/platform/windows/window.rs index c76a7879a4..cc2aa9591e 100644 --- a/crates/gpui/src/platform/windows/window.rs +++ b/crates/gpui/src/platform/windows/window.rs @@ -1514,6 +1514,8 @@ impl PlatformWindow for WindowsWindow { .ok(); } + fn set_app_id(&mut self, _app_id: &str) {} + fn set_background_appearance(&mut self, _background_appearance: WindowBackgroundAppearance) { // todo(windows) } diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index d5aaed8586..4d639b3737 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -600,10 +600,11 @@ impl Window { display_id, fullscreen, window_background, + app_id, } = options; let bounds = bounds.unwrap_or_else(|| default_bounds(display_id, cx)); - let platform_window = cx.platform.open_window( + let mut platform_window = cx.platform.open_window( handle, WindowParams { bounds, @@ -735,6 +736,10 @@ impl Window { }) }); + if let Some(app_id) = app_id { + platform_window.set_app_id(&app_id); + } + Window { handle, removed: false, @@ -1125,6 +1130,11 @@ impl<'a> WindowContext<'a> { self.window.platform_window.set_title(title); } + /// Sets the application identifier. + pub fn set_app_id(&mut self, app_id: &str) { + self.window.platform_window.set_app_id(app_id); + } + /// Sets the window background appearance. pub fn set_background_appearance(&mut self, background_appearance: WindowBackgroundAppearance) { self.window diff --git a/crates/semantic_index/src/chunking.rs b/crates/semantic_index/src/chunking.rs index da37afd78c..b0ddd73122 100644 --- a/crates/semantic_index/src/chunking.rs +++ b/crates/semantic_index/src/chunking.rs @@ -188,6 +188,7 @@ mod tests { kind: WindowKind::PopUp, is_movable: false, fullscreen: false, + app_id: None, } }; @@ -239,7 +240,7 @@ mod tests { // The break between chunks is right before the "Specify the display_id" comment assert_eq!(chunks[1].range.start, 1498); - assert_eq!(chunks[1].range.end, 2396); + assert_eq!(chunks[1].range.end, 2434); } #[test] diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index fbbec18601..7ec9b68731 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -102,6 +102,7 @@ pub fn build_window_options(display_uuid: Option, cx: &mut AppContext) -> display_id: display.map(|display| display.id()), fullscreen: false, window_background: cx.theme().window_background_appearance(), + app_id: Some("dev.zed.Zed".to_owned()), } }