diff --git a/CHANGELOG.md b/CHANGELOG.md index 87a7522e8b..6e14386f2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Unreleased` header. # Unreleased +- On X11, don't require XIM to run. - Fix compatibility with 32-bit platforms without 64-bit atomics. - On X11, fix swapped instance and general class names. - **Breaking:** Removed unnecessary generic parameter `T` from `EventLoopWindowTarget`. diff --git a/src/platform_impl/linux/x11/event_processor.rs b/src/platform_impl/linux/x11/event_processor.rs index d7d3b5c557..9e88f1d4ee 100644 --- a/src/platform_impl/linux/x11/event_processor.rs +++ b/src/platform_impl/linux/x11/event_processor.rs @@ -74,7 +74,11 @@ impl EventProcessor { // Handle IME requests. while let Ok(request) = self.ime_receiver.try_recv() { - let ime = window_target.ime.get_mut(); + let ime = match window_target.ime.as_mut() { + Some(ime) => ime, + None => continue, + }; + let ime = ime.get_mut(); match request { ImeRequest::Position(window_id, x, y) => { ime.send_xim_spot(window_id, x, y); @@ -792,10 +796,11 @@ impl EventProcessor { // Since all XIM stuff needs to happen from the same thread, we destroy the input // context here instead of when dropping the window. - wt.ime - .borrow_mut() - .remove_context(window as XWindow) - .expect("Failed to destroy input context"); + if let Some(ime) = wt.ime.as_ref() { + ime.borrow_mut() + .remove_context(window as XWindow) + .expect("Failed to destroy input context"); + } callback( &self.target, @@ -922,7 +927,11 @@ impl EventProcessor { }, }, ); - } else if let Some(ic) = wt.ime.borrow().get_context(window as XWindow) { + } else if let Some(ic) = wt + .ime + .as_ref() + .and_then(|ime| ime.borrow().get_context(window as XWindow)) + { let written = wt.xconn.lookup_utf8(ic, xev); if !written.is_empty() { let event = Event::WindowEvent { @@ -1191,10 +1200,11 @@ impl EventProcessor { // Set the timestamp. wt.xconn.set_timestamp(xev.time as xproto::Timestamp); - wt.ime - .borrow_mut() - .focus(xev.event) - .expect("Failed to focus input context"); + if let Some(ime) = wt.ime.as_ref() { + ime.borrow_mut() + .focus(xev.event) + .expect("Failed to focus input context"); + } if self.active_window == Some(window) { return; @@ -1262,10 +1272,11 @@ impl EventProcessor { return; } - wt.ime - .borrow_mut() - .unfocus(xev.event) - .expect("Failed to unfocus input context"); + if let Some(ime) = wt.ime.as_ref() { + ime.borrow_mut() + .unfocus(xev.event) + .expect("Failed to unfocus input context"); + } if self.active_window.take() == Some(window) { let window_id = mkwid(window); diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 4d733897a6..8f1db698ca 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -133,7 +133,7 @@ pub struct EventLoopWindowTarget { control_flow: Cell, exit: Cell>, root: xproto::Window, - ime: RefCell, + ime: Option>, windows: RefCell>>, redraw_sender: WakeSender, activation_sender: WakeSender, @@ -209,13 +209,15 @@ impl EventLoop { setlocale(LC_CTYPE, default_locale); } } - let ime = RefCell::new({ - let result = Ime::new(Arc::clone(&xconn), ime_event_sender); - if let Err(ImeCreationError::OpenFailure(ref state)) = result { - panic!("Failed to open input method: {state:#?}"); - } - result.expect("Failed to set input method destruction callback") - }); + + let ime = Ime::new(Arc::clone(&xconn), ime_event_sender); + if let Err(ImeCreationError::OpenFailure(state)) = ime.as_ref() { + warn!("Failed to open input method: {state:#?}"); + } else if let Err(err) = ime.as_ref() { + warn!("Failed to set input method destruction callback: {err:?}"); + } + + let ime = ime.ok().map(RefCell::new); let randr_event_offset = xconn .select_xrandr_input(root) diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index ecae94a08d..12eedb589a 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -555,9 +555,9 @@ impl UnownedWindow { leap!(xconn.select_xinput_events(window.xwindow, super::ALL_MASTER_DEVICES, mask)) .ignore_error(); - { - let result = event_loop - .ime + // Try to create input context for the window. + if let Some(ime) = event_loop.ime.as_ref() { + let result = ime .borrow_mut() .create_context(window.xwindow as ffi::Window, false); leap!(result);