From a1b65f7080fda20a9ab9fdc6f925d38e94df01af Mon Sep 17 00:00:00 2001 From: Julien Sanchez Date: Mon, 10 Feb 2020 06:37:06 +0100 Subject: [PATCH] Ignore locale if unsupported by X11 backend (#1445) This restores default portable 'C' locale when target locale is unsupported by X11 backend (Xlib). When target locale is unsupported by X11, some locale-dependent Xlib functions like `XSetLocaleModifiers` fail or have no effect triggering later failures and panics. When target locale is not valid, `setLocale` should normally leave the locale unchanged (`setLocale` returns 'C'). However, in some situations, locale is accepted by `setLocale` (`setLocale` returns the new locale) but the accepted locale is unsupported by Xlib (`XSupportsLocale` returns `false`). Fix #636 --- CHANGELOG.md | 1 + .../linux/x11/ime/input_method.rs | 3 ++- src/platform_impl/linux/x11/mod.rs | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5711e5a..d6775c2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - On Wayland, fix coordinates in touch events when scale factor isn't 1. - On Wayland, fix color from `close_button_icon_color` not applying. +- Ignore locale if unsupported by X11 backend # 0.21.0 (2020-02-04) diff --git a/src/platform_impl/linux/x11/ime/input_method.rs b/src/platform_impl/linux/x11/ime/input_method.rs index 42c4033e..142c1501 100644 --- a/src/platform_impl/linux/x11/ime/input_method.rs +++ b/src/platform_impl/linux/x11/ime/input_method.rs @@ -21,7 +21,8 @@ unsafe fn open_im(xconn: &Arc, locale_modifiers: &CStr) -> Option EventLoop { // Input methods will open successfully without setting the locale, but it won't be // possible to actually commit pre-edit sequences. unsafe { + // Remember default locale to restore it if target locale is unsupported + // by Xlib + let default_locale = setlocale(LC_CTYPE, ptr::null()); setlocale(LC_CTYPE, b"\0".as_ptr() as *const _); + + // Check if set locale is supported by Xlib. + // If not, calls to some Xlib functions like `XSetLocaleModifiers` + // will fail. + let locale_supported = (xconn.xlib.XSupportsLocale)() == 1; + if !locale_supported { + let unsupported_locale = setlocale(LC_CTYPE, ptr::null()); + warn!( + "Unsupported locale \"{}\". Restoring default locale \"{}\".", + CStr::from_ptr(unsupported_locale).to_string_lossy(), + CStr::from_ptr(default_locale).to_string_lossy() + ); + // Restore default locale + setlocale(LC_CTYPE, default_locale); + } } let ime = RefCell::new({ let result = Ime::new(Arc::clone(&xconn));