wayland: change some borrow_mut to borrow, reduce borrow scopes, fix two crashes (#9306)

Luke Jones created

Release Notes:

- N/A

Change summary

crates/gpui/src/platform/linux/wayland/client.rs | 33 ++++++++++-------
crates/gpui/src/platform/linux/wayland/window.rs | 20 ++++------
2 files changed, 29 insertions(+), 24 deletions(-)

Detailed changes

crates/gpui/src/platform/linux/wayland/client.rs 🔗

@@ -313,8 +313,7 @@ impl Client for WaylandClient {
         }
         .to_string();
 
-        let mut cursor_state = self.state.cursor_state.borrow_mut();
-        cursor_state.cursor_icon_name = cursor_icon_name;
+        self.state.cursor_state.borrow_mut().cursor_icon_name = cursor_icon_name;
     }
 
     fn get_clipboard(&self) -> Rc<RefCell<dyn ClipboardProvider>> {
@@ -819,21 +818,21 @@ fn linux_button_to_gpui(button: u32) -> Option<MouseButton> {
 
 impl Dispatch<wl_pointer::WlPointer, ()> for WaylandClientState {
     fn event(
-        state: &mut Self,
+        self_state: &mut Self,
         wl_pointer: &wl_pointer::WlPointer,
         event: wl_pointer::Event,
         data: &(),
         conn: &Connection,
         qh: &QueueHandle<Self>,
     ) {
-        let mut cursor_state = state.cursor_state.borrow_mut();
-        let mut state = state.client_state_inner.borrow_mut();
-
-        if cursor_state.cursor.is_none() {
-            cursor_state.cursor = Some(Cursor::new(&conn, &state.compositor, &qh, &state.shm, 24));
+        let mut state = self_state.client_state_inner.borrow_mut();
+        {
+            let mut cursor_state = self_state.cursor_state.borrow_mut();
+            if cursor_state.cursor.is_none() {
+                cursor_state.cursor =
+                    Some(Cursor::new(&conn, &state.compositor, &qh, &state.shm, 24));
+            }
         }
-        let cursor_icon_name = cursor_state.cursor_icon_name.clone();
-        let mut cursor: &mut Cursor = cursor_state.cursor.as_mut().unwrap();
 
         match event {
             wl_pointer::Event::Enter {
@@ -852,8 +851,12 @@ impl Dispatch<wl_pointer::WlPointer, ()> for WaylandClientState {
                 }
                 if mouse_focused_window.is_some() {
                     state.mouse_focused_window = mouse_focused_window;
-                    cursor.set_serial_id(serial);
-                    cursor.set_icon(&wl_pointer, cursor_icon_name);
+                    let mut cursor_state = self_state.cursor_state.borrow_mut();
+                    let cursor_icon_name = cursor_state.cursor_icon_name.clone();
+                    if let Some(mut cursor) = cursor_state.cursor.as_mut() {
+                        cursor.set_serial_id(serial);
+                        cursor.set_icon(&wl_pointer, cursor_icon_name);
+                    }
                 }
 
                 state.mouse_location = Some(Point {
@@ -881,7 +884,11 @@ impl Dispatch<wl_pointer::WlPointer, ()> for WaylandClientState {
                         modifiers: state.modifiers,
                     }),
                 );
-                cursor.set_icon(&wl_pointer, cursor_icon_name);
+                let mut cursor_state = self_state.cursor_state.borrow_mut();
+                let cursor_icon_name = cursor_state.cursor_icon_name.clone();
+                if let Some(mut cursor) = cursor_state.cursor.as_mut() {
+                    cursor.set_icon(&wl_pointer, cursor_icon_name);
+                }
             }
             wl_pointer::Event::Button {
                 button,

crates/gpui/src/platform/linux/wayland/window.rs 🔗

@@ -43,7 +43,6 @@ struct WaylandWindowInner {
     renderer: BladeRenderer,
     bounds: Bounds<u32>,
     scale: f32,
-    fullscreen: bool,
     input_handler: Option<PlatformInputHandler>,
     decoration_state: WaylandDecorationState,
 }
@@ -102,7 +101,6 @@ impl WaylandWindowInner {
             renderer: BladeRenderer::new(gpu, extent),
             bounds,
             scale: 1.0,
-            fullscreen: false,
             input_handler: None,
 
             // On wayland, decorations are by default provided by the client
@@ -118,6 +116,7 @@ pub(crate) struct WaylandWindowState {
     pub(crate) toplevel: Arc<xdg_toplevel::XdgToplevel>,
     pub(crate) outputs: RefCell<HashSet<ObjectId>>,
     viewport: Option<wp_viewport::WpViewport>,
+    fullscreen: RefCell<bool>,
 }
 
 impl WaylandWindowState {
@@ -136,6 +135,7 @@ impl WaylandWindowState {
             outputs: RefCell::new(HashSet::default()),
             toplevel,
             viewport,
+            fullscreen: RefCell::new(false),
         }
     }
 
@@ -197,7 +197,6 @@ impl WaylandWindowState {
     }
 
     pub fn resize(&self, width: Option<NonZeroU32>, height: Option<NonZeroU32>) {
-        let scale = self.inner.borrow_mut().scale;
         self.set_size_and_scale(width, height, None);
     }
 
@@ -210,7 +209,7 @@ impl WaylandWindowState {
         if let Some(ref mut fun) = callbacks.fullscreen {
             fun(fullscreen)
         }
-        self.inner.borrow_mut().fullscreen = fullscreen;
+        self.fullscreen.replace(fullscreen);
     }
 
     /// Notifies the window of the state of the decorations.
@@ -285,7 +284,7 @@ impl PlatformWindow for WaylandWindow {
     }
 
     fn content_size(&self) -> Size<Pixels> {
-        let inner = self.0.inner.borrow_mut();
+        let inner = self.0.inner.borrow();
         Size {
             width: Pixels(inner.bounds.size.width as f32),
             height: Pixels(inner.bounds.size.height as f32),
@@ -293,7 +292,7 @@ impl PlatformWindow for WaylandWindow {
     }
 
     fn scale_factor(&self) -> f32 {
-        self.0.inner.borrow_mut().scale
+        self.0.inner.borrow().scale
     }
 
     // todo(linux)
@@ -363,7 +362,7 @@ impl PlatformWindow for WaylandWindow {
     }
 
     fn toggle_fullscreen(&self) {
-        if !self.0.inner.borrow().fullscreen {
+        if !(*self.0.fullscreen.borrow()) {
             self.0.toplevel.set_fullscreen(None);
         } else {
             self.0.toplevel.unset_fullscreen();
@@ -371,7 +370,7 @@ impl PlatformWindow for WaylandWindow {
     }
 
     fn is_fullscreen(&self) -> bool {
-        self.0.inner.borrow_mut().fullscreen
+        *self.0.fullscreen.borrow()
     }
 
     fn on_request_frame(&self, callback: Box<dyn FnMut()>) {
@@ -416,12 +415,11 @@ impl PlatformWindow for WaylandWindow {
     }
 
     fn draw(&self, scene: &Scene) {
-        let mut inner = self.0.inner.borrow_mut();
-        inner.renderer.draw(scene);
+        self.0.inner.borrow_mut().renderer.draw(scene);
     }
 
     fn sprite_atlas(&self) -> Arc<dyn PlatformAtlas> {
-        let inner = self.0.inner.borrow_mut();
+        let inner = self.0.inner.borrow();
         inner.renderer.sprite_atlas().clone()
     }
 }