gpui: Fix `snap_to_window_with_margin` when window has client inset (#27330)

Jason Lee created

Release Notes:

- Fixed popup menu snap to window to leave margin on Linux.

This change to continue #17159 to fix same thing on Linux.

| Before | After |
| -- | -- |
| ![Pasted
image](https://github.com/user-attachments/assets/3129d42c-7253-4a3f-a428-86e2a3df38ff)
|
![image](https://github.com/user-attachments/assets/8dc83377-9df7-45ba-805b-1cfdea612ae0)
|

Change summary

crates/gpui/src/elements/anchored.rs |  6 ++++--
crates/gpui/src/window.rs            | 10 +++++++++-
2 files changed, 13 insertions(+), 3 deletions(-)

Detailed changes

crates/gpui/src/elements/anchored.rs 🔗

@@ -3,7 +3,7 @@ use taffy::style::{Display, Position};
 
 use crate::{
     AnyElement, App, Axis, Bounds, Corner, Edges, Element, GlobalElementId, IntoElement, LayoutId,
-    ParentElement, Pixels, Point, Size, Style, Window, point,
+    ParentElement, Pixels, Point, Size, Style, Window, point, px,
 };
 
 /// The state that the anchored element element uses to track its children.
@@ -175,10 +175,12 @@ impl Element for Anchored {
             }
         }
 
+        let client_inset = window.client_inset.unwrap_or(px(0.));
         let edges = match self.fit_mode {
             AnchoredFitMode::SnapToWindowWithMargin(edges) => edges,
             _ => Edges::default(),
-        };
+        }
+        .map(|edge| *edge + client_inset);
 
         // Snap the horizontal edges of the anchored element to the horizontal edges of the window if
         // its horizontal bounds overflow, aligning to the left if it is wider than the limits.

crates/gpui/src/window.rs 🔗

@@ -646,6 +646,7 @@ pub struct Window {
     pending_modifier: ModifierState,
     pub(crate) pending_input_observers: SubscriberSet<(), AnyObserver>,
     prompt: Option<RenderablePromptHandle>,
+    pub(crate) client_inset: Option<Pixels>,
 }
 
 #[derive(Clone, Debug, Default)]
@@ -931,6 +932,7 @@ impl Window {
             pending_modifier: ModifierState::default(),
             pending_input_observers: SubscriberSet::new(),
             prompt: None,
+            client_inset: None,
         })
     }
 
@@ -1387,10 +1389,16 @@ impl Window {
     }
 
     /// When using client side decorations, set this to the width of the invisible decorations (Wayland and X11)
-    pub fn set_client_inset(&self, inset: Pixels) {
+    pub fn set_client_inset(&mut self, inset: Pixels) {
+        self.client_inset = Some(inset);
         self.platform_window.set_client_inset(inset);
     }
 
+    /// Returns the client_inset value by [`Self::set_client_inset`].
+    pub fn client_inset(&self) -> Option<Pixels> {
+        self.client_inset
+    }
+
     /// Returns whether the title bar window controls need to be rendered by the application (Wayland and X11)
     pub fn window_decorations(&self) -> Decorations {
         self.platform_window.window_decorations()