use cache for x11

Junkui Zhang created

Change summary

crates/gpui/src/platform/linux/x11/client.rs | 24 +++++++++++++++++----
1 file changed, 19 insertions(+), 5 deletions(-)

Detailed changes

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

@@ -207,7 +207,8 @@ pub struct X11ClientState {
     previous_xkb_state: XKBStateNotiy,
     keyboard_layout: LinuxKeyboardLayout,
     pub(crate) keyboard_layout: Box<LinuxKeyboardLayout>,
-    pub(crate) keyboard_mapper: LinuxKeyboardMapper,
+    pub(crate) keyboard_mapper: Rc<LinuxKeyboardMapper>,
+    pub(crate) keyboard_mapper_cache: HashMap<String, Rc<LinuxKeyboardMapper>>,
     pub(crate) ximc: Option<X11rbClient<Rc<XCBConnection>>>,
     pub(crate) xim_handler: Option<XimHandler>,
     pub modifiers: Modifiers,
@@ -428,7 +429,9 @@ impl X11Client {
             .to_string();
         let keyboard_layout = LinuxKeyboardLayout::new(layout_name.into());
         let keyboard_layout = Box::new(LinuxKeyboardLayout::new(&xkb_state));
-        let keyboard_mapper = LinuxKeyboardMapper::new(0, 0, 0);
+        let keyboard_mapper = Rc::new(LinuxKeyboardMapper::new(0, 0, 0));
+        let mut keyboard_mapper_cache = HashMap::default();
+        keyboard_mapper_cache.insert(keyboard_layout.id().to_string(), keyboard_mapper.clone());
 
         let gpu_context = BladeContext::new().context("Unable to init GPU context")?;
 
@@ -523,6 +526,7 @@ impl X11Client {
             previous_xkb_state: XKBStateNotiy::default(),
             keyboard_layout,
             keyboard_mapper,
+            keyboard_mapper_cache,
             ximc,
             xim_handler,
 
@@ -981,12 +985,22 @@ impl X11Client {
                     latched_layout,
                     locked_layout,
                 };
+                let keyboard_layout = LinuxKeyboardLayout::new(&xkb_state);
+                println!("X11 Keyboard layout: {:#?}", keyboard_layout.id());
                 state.xkb = xkb_state;
                 drop(state);
                 self.handle_keyboard_layout_change();
-                state.keyboard_mapper = LinuxKeyboardMapper::new(0, 0, 0);
-                let layout = LinuxKeyboardLayout::new(&state.xkb).id().to_string();
-                println!("X11 Keyboard layout: {:#?}", layout);
+                state.keyboard_mapper =
+                    if let Some(mapper) = state.keyboard_mapper_cache.get(keyboard_layout.id()) {
+                        Rc::clone(mapper)
+                    } else {
+                        let mapper = Rc::new(LinuxKeyboardMapper::new(0, 0, 0));
+                        state
+                            .keyboard_mapper_cache
+                            .insert(keyboard_layout.id().to_string(), Rc::clone(&mapper));
+                        mapper
+                    };
+                state.keyboard_layout = Box::new(keyboard_layout);
             }
             Event::XkbStateNotify(event) => {
                 let mut state = self.0.borrow_mut();