Skip to content

Commit

Permalink
Merge branch 'master' into fix-x11-serial
Browse files Browse the repository at this point in the history
  • Loading branch information
kchibisov authored Feb 3, 2025
2 parents fc4d857 + a6998af commit b7343e4
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 37 deletions.
5 changes: 5 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ All patches have to be sent on Github as [pull requests][prs]. To simplify your
life during review it's recommended to check the "give contributors write access
to the branch" checkbox.

We use unstable Rustfmt options across the project, so please run
`cargo +nightly fmt` before submitting your work. If you are unable to do so,
the maintainers can do it for you before merging, just state so in your pull
request description.

#### Handling review

During the review process certain events could require an action from your side,
Expand Down
1 change: 1 addition & 0 deletions src/changelog/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,4 @@ changelog entry.
- On macOS, fixed redundant `SurfaceResized` event at window creation.
- On Windows, fixed the event loop not waking on accessibility requests.
- On X11, fixed cursor grab mode state tracking on error.
- On X11, fixed crash with uim
8 changes: 2 additions & 6 deletions src/platform_impl/linux/x11/ime/callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,19 +122,15 @@ unsafe fn replace_im(inner: *mut ImeInner) -> Result<(), ReplaceImError> {
let is_allowed =
old_context.as_ref().map(|old_context| old_context.is_allowed()).unwrap_or_default();

// We can't use the style from the old context here, since it may change on reload, so
// pick style from the new XIM based on the old state.
let style = if is_allowed { new_im.preedit_style } else { new_im.none_style };

let new_context = {
let result = unsafe {
ImeContext::new(
xconn,
new_im.im,
style,
&new_im,
*window,
spot,
(*inner).event_sender.clone(),
is_allowed,
)
};
if result.is_err() {
Expand Down
22 changes: 13 additions & 9 deletions src/platform_impl/linux/x11/ime/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{fmt, mem, ptr};
use x11_dl::xlib::{XIMCallback, XIMPreeditCaretCallbackStruct, XIMPreeditDrawCallbackStruct};

use super::{ffi, util, XConnection, XError};
use crate::platform_impl::platform::x11::ime::input_method::{Style, XIMStyle};
use crate::platform_impl::platform::x11::ime::input_method::{InputMethod, Style, XIMStyle};
use crate::platform_impl::platform::x11::ime::{ImeEvent, ImeEventSender};

/// IME creation error.
Expand Down Expand Up @@ -197,7 +197,7 @@ struct ImeContextClientData {
pub struct ImeContext {
pub(crate) ic: ffi::XIC,
pub(crate) ic_spot: ffi::XPoint,
pub(crate) style: Style,
pub(crate) allowed: bool,
// Since the data is passed shared between X11 XIM callbacks, but couldn't be directly free
// from there we keep the pointer to automatically deallocate it.
_client_data: Box<ImeContextClientData>,
Expand All @@ -206,11 +206,11 @@ pub struct ImeContext {
impl ImeContext {
pub(crate) unsafe fn new(
xconn: &Arc<XConnection>,
im: ffi::XIM,
style: Style,
im: &InputMethod,
window: ffi::Window,
ic_spot: Option<ffi::XPoint>,
event_sender: ImeEventSender,
allowed: bool,
) -> Result<Self, ImeContextCreationError> {
let client_data = Box::into_raw(Box::new(ImeContextClientData {
window,
Expand All @@ -219,20 +219,24 @@ impl ImeContext {
cursor_pos: 0,
}));

let style = if allowed { im.preedit_style } else { im.none_style };

let ic = match style as _ {
Style::Preedit(style) => unsafe {
ImeContext::create_preedit_ic(
xconn,
im,
im.im,
style,
window,
client_data as ffi::XPointer,
)
},
Style::Nothing(style) => unsafe {
ImeContext::create_nothing_ic(xconn, im, style, window)
ImeContext::create_nothing_ic(xconn, im.im, style, window)
},
Style::None(style) => unsafe {
ImeContext::create_none_ic(xconn, im.im, style, window)
},
Style::None(style) => unsafe { ImeContext::create_none_ic(xconn, im, style, window) },
}
.ok_or(ImeContextCreationError::Null)?;

Expand All @@ -241,7 +245,7 @@ impl ImeContext {
let mut context = ImeContext {
ic,
ic_spot: ffi::XPoint { x: 0, y: 0 },
style,
allowed,
_client_data: unsafe { Box::from_raw(client_data) },
};

Expand Down Expand Up @@ -348,7 +352,7 @@ impl ImeContext {
}

pub fn is_allowed(&self) -> bool {
!matches!(self.style, Style::None(_))
self.allowed
}

// Set the spot for preedit text. Setting spot isn't working with libX11 when preedit callbacks
Expand Down
4 changes: 1 addition & 3 deletions src/platform_impl/linux/x11/ime/input_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@ impl InputMethod {
}

let preedit_style = preedit_style.unwrap_or_else(|| none_style.unwrap());
// Always initialize none style even when it's not advertised, since it seems to work
// regardless...
let none_style = none_style.unwrap_or(Style::None(XIM_NONE_STYLE));
let none_style = none_style.unwrap_or(preedit_style);

Some(InputMethod { im, _name: name, preedit_style, none_style })
}
Expand Down
24 changes: 5 additions & 19 deletions src/platform_impl/linux/x11/ime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ use std::sync::Arc;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use tracing::debug;

use self::callbacks::*;
use self::context::ImeContext;
pub use self::context::ImeContextCreationError;
use self::inner::{close_im, ImeInner};
use self::input_method::{PotentialInputMethods, Style};
use self::input_method::PotentialInputMethods;
use super::{ffi, util, XConnection, XError};

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -113,39 +112,26 @@ impl Ime {
pub fn create_context(
&mut self,
window: ffi::Window,
with_preedit: bool,
with_ime: bool,
) -> Result<bool, ImeContextCreationError> {
let context = if self.is_destroyed() {
// Create empty entry in map, so that when IME is rebuilt, this window has a context.
None
} else {
let im = self.inner.im.as_ref().unwrap();
let style = if with_preedit { im.preedit_style } else { im.none_style };

let context = unsafe {
ImeContext::new(
&self.inner.xconn,
im.im,
style,
im,
window,
None,
self.inner.event_sender.clone(),
with_ime,
)?
};

// Check the state on the context, since it could fail to enable or disable preedit.
let event = if matches!(style, Style::None(_)) {
if with_preedit {
debug!("failed to create IME context with preedit support.")
}
ImeEvent::Disabled
} else {
if !with_preedit {
debug!("failed to create IME context without preedit support.")
}
ImeEvent::Enabled
};

let event = if context.is_allowed() { ImeEvent::Enabled } else { ImeEvent::Disabled };
self.inner.event_sender.send((window, event)).expect("Failed to send enabled event");

Some(context)
Expand Down

0 comments on commit b7343e4

Please sign in to comment.