On X11, fix crash when can't disable IME

Fixes #2402.
This commit is contained in:
Kirill Chibisov 2022-07-30 17:15:57 +03:00 committed by GitHub
parent bf537009d9
commit 95246d81c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 17 deletions

View file

@ -1,12 +1,13 @@
use std::mem::transmute;
use std::ffi::CStr;
use std::os::raw::c_short;
use std::ptr;
use std::sync::Arc;
use std::{mem, ptr};
use x11_dl::xlib::{XIMCallback, XIMPreeditCaretCallbackStruct, XIMPreeditDrawCallbackStruct};
use crate::platform_impl::platform::x11::ime::{ImeEvent, ImeEventSender};
use super::{ffi, util, XConnection, XError};
use crate::platform_impl::platform::x11::ime::{ImeEvent, ImeEventSender};
use std::ffi::CStr;
use x11_dl::xlib::{XIMCallback, XIMPreeditCaretCallbackStruct, XIMPreeditDrawCallbackStruct};
/// IME creation error.
#[derive(Debug)]
@ -163,7 +164,7 @@ struct PreeditCallbacks {
impl PreeditCallbacks {
pub fn new(client_data: ffi::XPointer) -> PreeditCallbacks {
let start_callback = create_xim_callback(client_data, unsafe {
transmute(preedit_start_callback as usize)
mem::transmute(preedit_start_callback as usize)
});
let done_callback = create_xim_callback(client_data, preedit_done_callback);
let caret_callback = create_xim_callback(client_data, preedit_caret_callback);

View file

@ -120,7 +120,33 @@ impl Ime {
// Create empty entry in map, so that when IME is rebuilt, this window has a context.
None
} else {
let event = if with_preedit {
let context = unsafe {
ImeContext::new(
&self.inner.xconn,
self.inner.im,
window,
None,
with_preedit,
self.inner.event_sender.clone(),
)
.or_else(|_| {
debug!(
"failed to create an IME context {} preedit support",
if with_preedit { "with" } else { "without" }
);
ImeContext::new(
&self.inner.xconn,
self.inner.im,
window,
None,
!with_preedit,
self.inner.event_sender.clone(),
)
})
}?;
// Check the state on the context, since it could fail to enable or disable preedit.
let event = if context.is_allowed {
ImeEvent::Enabled
} else {
// There's no IME without preedit.
@ -132,16 +158,7 @@ impl Ime {
.send((window, event))
.expect("Failed to send enabled event");
Some(unsafe {
ImeContext::new(
&self.inner.xconn,
self.inner.im,
window,
None,
with_preedit,
self.inner.event_sender.clone(),
)
}?)
Some(context)
};
self.inner.contexts.insert(window, context);
Ok(!self.is_destroyed())