Browse Source

Fix segfault on Linux when typing in a TexBox

See https://github.com/AvaloniaUI/Avalonia/issues/12049
pull/12313/head
Luc 3 years ago
parent
commit
c834b04496
  1. 20
      src/Avalonia.X11/X11Info.cs
  2. 10
      src/Avalonia.X11/X11Platform.cs
  3. 15
      src/Avalonia.X11/X11Window.Ime.cs
  4. 2
      src/Avalonia.X11/XLib.cs

20
src/Avalonia.X11/X11Info.cs

@ -34,7 +34,10 @@ namespace Avalonia.X11
public bool HasXim { get; set; }
public bool HasXSync { get; set; }
public IntPtr DefaultFontSet { get; set; }
[DllImport("libc")]
private static extern void setlocale(int type, string s);
public unsafe X11Info(IntPtr display, IntPtr deferredDisplay, bool useXim)
{
Display = display;
@ -48,7 +51,10 @@ namespace Avalonia.X11
DefaultFontSet = XCreateFontSet(Display, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
out var _, out var _, IntPtr.Zero);
// We have problems with text input otherwise
setlocale(0, "");
if (useXim)
{
XSetLocaleModifiers("");
@ -59,7 +65,15 @@ namespace Avalonia.X11
if (Xim == IntPtr.Zero)
{
XSetLocaleModifiers("@im=none");
if (XSetLocaleModifiers("@im=none") == IntPtr.Zero)
{
setlocale(0, "en_US.UTF-8");
if (XSetLocaleModifiers("@im=none") == IntPtr.Zero)
{
setlocale(0, "C.UTF-8");
XSetLocaleModifiers("@im=none");
}
}
Xim = XOpenIM(display, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
}

10
src/Avalonia.X11/X11Platform.cs

@ -36,12 +36,11 @@ namespace Avalonia.X11
public IntPtr OrphanedWindow { get; private set; }
public X11Globals Globals { get; private set; }
public ManualRawEventGrouperDispatchQueue EventGrouperDispatchQueue { get; } = new();
[DllImport("libc")]
private static extern void setlocale(int type, string s);
public void Initialize(X11PlatformOptions options)
{
Options = options;
bool useXim = false;
if (EnableIme(options))
{
@ -50,9 +49,6 @@ namespace Avalonia.X11
useXim = true;
}
// We have problems with text input otherwise
setlocale(0, "");
XInitThreads();
Display = XOpenDisplay(IntPtr.Zero);
if (Display == IntPtr.Zero)
@ -64,7 +60,7 @@ namespace Avalonia.X11
OrphanedWindow = XCreateSimpleWindow(Display, XDefaultRootWindow(Display), 0, 0, 1, 1, 0, IntPtr.Zero,
IntPtr.Zero);
XError.Init();
Info = new X11Info(Display, DeferredDisplay, useXim);
Globals = new X11Globals(this);
//TODO: log

15
src/Avalonia.X11/X11Window.Ime.cs

@ -133,14 +133,21 @@ namespace Avalonia.X11
{
if (ImeBuffer == IntPtr.Zero)
ImeBuffer = Marshal.AllocHGlobal(ImeBufferSize);
var len = Xutf8LookupString(_xic, ref ev, ImeBuffer.ToPointer(), ImeBufferSize,
out _, out var istatus);
var status = (XLookupStatus)istatus;
IntPtr istatus;
int len;
if(_xic != IntPtr.Zero)
len = Xutf8LookupString(_xic, ref ev, ImeBuffer.ToPointer(),
ImeBufferSize, out _, out istatus);
else
len = XLookupString(ref ev, ImeBuffer.ToPointer(), ImeBufferSize,
out _, out istatus);
if (len == 0)
return null;
var status = (XLookupStatus)istatus;
string text;
if (status == XLookupStatus.XBufferOverflow)
return null;

2
src/Avalonia.X11/XLib.cs

@ -468,7 +468,7 @@ namespace Avalonia.X11
public static extern unsafe int XLookupString(ref XEvent xevent, void* buffer, int num_bytes, out IntPtr keysym, out IntPtr status);
[DllImport (libX11)]
public static extern unsafe int Xutf8LookupString(IntPtr xic, ref XEvent xevent, void* buffer, int num_bytes, out IntPtr keysym, out UIntPtr status);
public static extern unsafe int Xutf8LookupString(IntPtr xic, ref XEvent xevent, void* buffer, int num_bytes, out IntPtr keysym, out IntPtr status);
[DllImport (libX11)]
public static extern unsafe int Xutf8LookupString(IntPtr xic, XEvent* xevent, void* buffer, int num_bytes, out IntPtr keysym, out IntPtr status);

Loading…
Cancel
Save