On X11, don't require XIM to be present
In general, we may want to use xinput v2 for keyboard input in such cases, so we have compose going, but for now just don't crash if there's no XIM.
This commit is contained in:
parent
83012f4c1c
commit
ea70f773d3
4 changed files with 39 additions and 25 deletions
|
|
@ -11,6 +11,7 @@ Unreleased` header.
|
||||||
|
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
|
- On X11, don't require XIM to run.
|
||||||
- Fix compatibility with 32-bit platforms without 64-bit atomics.
|
- Fix compatibility with 32-bit platforms without 64-bit atomics.
|
||||||
- On X11, fix swapped instance and general class names.
|
- On X11, fix swapped instance and general class names.
|
||||||
- **Breaking:** Removed unnecessary generic parameter `T` from `EventLoopWindowTarget`.
|
- **Breaking:** Removed unnecessary generic parameter `T` from `EventLoopWindowTarget`.
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,11 @@ impl EventProcessor {
|
||||||
|
|
||||||
// Handle IME requests.
|
// Handle IME requests.
|
||||||
while let Ok(request) = self.ime_receiver.try_recv() {
|
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 {
|
match request {
|
||||||
ImeRequest::Position(window_id, x, y) => {
|
ImeRequest::Position(window_id, x, y) => {
|
||||||
ime.send_xim_spot(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
|
// Since all XIM stuff needs to happen from the same thread, we destroy the input
|
||||||
// context here instead of when dropping the window.
|
// context here instead of when dropping the window.
|
||||||
wt.ime
|
if let Some(ime) = wt.ime.as_ref() {
|
||||||
.borrow_mut()
|
ime.borrow_mut()
|
||||||
.remove_context(window as XWindow)
|
.remove_context(window as XWindow)
|
||||||
.expect("Failed to destroy input context");
|
.expect("Failed to destroy input context");
|
||||||
|
}
|
||||||
|
|
||||||
callback(
|
callback(
|
||||||
&self.target,
|
&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);
|
let written = wt.xconn.lookup_utf8(ic, xev);
|
||||||
if !written.is_empty() {
|
if !written.is_empty() {
|
||||||
let event = Event::WindowEvent {
|
let event = Event::WindowEvent {
|
||||||
|
|
@ -1191,10 +1200,11 @@ impl EventProcessor {
|
||||||
// Set the timestamp.
|
// Set the timestamp.
|
||||||
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
wt.xconn.set_timestamp(xev.time as xproto::Timestamp);
|
||||||
|
|
||||||
wt.ime
|
if let Some(ime) = wt.ime.as_ref() {
|
||||||
.borrow_mut()
|
ime.borrow_mut()
|
||||||
.focus(xev.event)
|
.focus(xev.event)
|
||||||
.expect("Failed to focus input context");
|
.expect("Failed to focus input context");
|
||||||
|
}
|
||||||
|
|
||||||
if self.active_window == Some(window) {
|
if self.active_window == Some(window) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -1262,10 +1272,11 @@ impl EventProcessor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wt.ime
|
if let Some(ime) = wt.ime.as_ref() {
|
||||||
.borrow_mut()
|
ime.borrow_mut()
|
||||||
.unfocus(xev.event)
|
.unfocus(xev.event)
|
||||||
.expect("Failed to unfocus input context");
|
.expect("Failed to unfocus input context");
|
||||||
|
}
|
||||||
|
|
||||||
if self.active_window.take() == Some(window) {
|
if self.active_window.take() == Some(window) {
|
||||||
let window_id = mkwid(window);
|
let window_id = mkwid(window);
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ pub struct EventLoopWindowTarget {
|
||||||
control_flow: Cell<ControlFlow>,
|
control_flow: Cell<ControlFlow>,
|
||||||
exit: Cell<Option<i32>>,
|
exit: Cell<Option<i32>>,
|
||||||
root: xproto::Window,
|
root: xproto::Window,
|
||||||
ime: RefCell<Ime>,
|
ime: Option<RefCell<Ime>>,
|
||||||
windows: RefCell<HashMap<WindowId, Weak<UnownedWindow>>>,
|
windows: RefCell<HashMap<WindowId, Weak<UnownedWindow>>>,
|
||||||
redraw_sender: WakeSender<WindowId>,
|
redraw_sender: WakeSender<WindowId>,
|
||||||
activation_sender: WakeSender<ActivationToken>,
|
activation_sender: WakeSender<ActivationToken>,
|
||||||
|
|
@ -209,13 +209,15 @@ impl<T: 'static> EventLoop<T> {
|
||||||
setlocale(LC_CTYPE, default_locale);
|
setlocale(LC_CTYPE, default_locale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let ime = RefCell::new({
|
|
||||||
let result = Ime::new(Arc::clone(&xconn), ime_event_sender);
|
let ime = Ime::new(Arc::clone(&xconn), ime_event_sender);
|
||||||
if let Err(ImeCreationError::OpenFailure(ref state)) = result {
|
if let Err(ImeCreationError::OpenFailure(state)) = ime.as_ref() {
|
||||||
panic!("Failed to open input method: {state:#?}");
|
warn!("Failed to open input method: {state:#?}");
|
||||||
}
|
} else if let Err(err) = ime.as_ref() {
|
||||||
result.expect("Failed to set input method destruction callback")
|
warn!("Failed to set input method destruction callback: {err:?}");
|
||||||
});
|
}
|
||||||
|
|
||||||
|
let ime = ime.ok().map(RefCell::new);
|
||||||
|
|
||||||
let randr_event_offset = xconn
|
let randr_event_offset = xconn
|
||||||
.select_xrandr_input(root)
|
.select_xrandr_input(root)
|
||||||
|
|
|
||||||
|
|
@ -555,9 +555,9 @@ impl UnownedWindow {
|
||||||
leap!(xconn.select_xinput_events(window.xwindow, super::ALL_MASTER_DEVICES, mask))
|
leap!(xconn.select_xinput_events(window.xwindow, super::ALL_MASTER_DEVICES, mask))
|
||||||
.ignore_error();
|
.ignore_error();
|
||||||
|
|
||||||
{
|
// Try to create input context for the window.
|
||||||
let result = event_loop
|
if let Some(ime) = event_loop.ime.as_ref() {
|
||||||
.ime
|
let result = ime
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.create_context(window.xwindow as ffi::Window, false);
|
.create_context(window.xwindow as ffi::Window, false);
|
||||||
leap!(result);
|
leap!(result);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue