mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
At least make it not drop character after conversion with google IME
This commit is contained in:
parent
c326537f9f
commit
637ba78956
1 changed files with 138 additions and 28 deletions
|
|
@ -18,7 +18,9 @@ using Dalamud.Interface.Utility;
|
||||||
|
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
|
#if IMEDEBUG
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
#endif
|
||||||
|
|
||||||
using TerraFX.Interop.Windows;
|
using TerraFX.Interop.Windows;
|
||||||
|
|
||||||
|
|
@ -267,6 +269,50 @@ internal sealed unsafe class DalamudIme : IDisposable, IServiceType
|
||||||
{
|
{
|
||||||
var invalidTarget = TextState->Id == 0 || (TextState->Flags & ImGuiInputTextFlags.ReadOnly) != 0;
|
var invalidTarget = TextState->Id == 0 || (TextState->Flags & ImGuiInputTextFlags.ReadOnly) != 0;
|
||||||
|
|
||||||
|
#if IMEDEBUG
|
||||||
|
switch (args.Message)
|
||||||
|
{
|
||||||
|
case WM.WM_IME_NOTIFY:
|
||||||
|
Log.Verbose($"{nameof(WM.WM_IME_NOTIFY)}({ImeDebug.ImnName((int)args.WParam)}, 0x{args.LParam:X})");
|
||||||
|
break;
|
||||||
|
case WM.WM_IME_CONTROL:
|
||||||
|
Log.Verbose(
|
||||||
|
$"{nameof(WM.WM_IME_CONTROL)}({ImeDebug.ImcName((int)args.WParam)}, 0x{args.LParam:X})");
|
||||||
|
break;
|
||||||
|
case WM.WM_IME_REQUEST:
|
||||||
|
Log.Verbose(
|
||||||
|
$"{nameof(WM.WM_IME_REQUEST)}({ImeDebug.ImrName((int)args.WParam)}, 0x{args.LParam:X})");
|
||||||
|
break;
|
||||||
|
case WM.WM_IME_SELECT:
|
||||||
|
Log.Verbose($"{nameof(WM.WM_IME_SELECT)}({(int)args.WParam != 0}, 0x{args.LParam:X})");
|
||||||
|
break;
|
||||||
|
case WM.WM_IME_STARTCOMPOSITION:
|
||||||
|
Log.Verbose($"{nameof(WM.WM_IME_STARTCOMPOSITION)}()");
|
||||||
|
break;
|
||||||
|
case WM.WM_IME_COMPOSITION:
|
||||||
|
Log.Verbose(
|
||||||
|
$"{nameof(WM.WM_IME_COMPOSITION)}({(char)args.WParam}, {ImeDebug.GcsName((int)args.LParam)})");
|
||||||
|
break;
|
||||||
|
case WM.WM_IME_COMPOSITIONFULL:
|
||||||
|
Log.Verbose($"{nameof(WM.WM_IME_COMPOSITIONFULL)}()");
|
||||||
|
break;
|
||||||
|
case WM.WM_IME_ENDCOMPOSITION:
|
||||||
|
Log.Verbose($"{nameof(WM.WM_IME_ENDCOMPOSITION)}()");
|
||||||
|
break;
|
||||||
|
case WM.WM_IME_CHAR:
|
||||||
|
Log.Verbose($"{nameof(WM.WM_IME_CHAR)}({(char)args.WParam}, 0x{args.LParam:X})");
|
||||||
|
break;
|
||||||
|
case WM.WM_IME_KEYDOWN:
|
||||||
|
Log.Verbose($"{nameof(WM.WM_IME_KEYDOWN)}({(char)args.WParam}, 0x{args.LParam:X})");
|
||||||
|
break;
|
||||||
|
case WM.WM_IME_KEYUP:
|
||||||
|
Log.Verbose($"{nameof(WM.WM_IME_KEYUP)}({(char)args.WParam}, 0x{args.LParam:X})");
|
||||||
|
break;
|
||||||
|
case WM.WM_IME_SETCONTEXT:
|
||||||
|
Log.Verbose($"{nameof(WM.WM_IME_SETCONTEXT)}({(int)args.WParam != 0}, 0x{args.LParam:X})");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
switch (args.Message)
|
switch (args.Message)
|
||||||
{
|
{
|
||||||
case WM.WM_IME_NOTIFY
|
case WM.WM_IME_NOTIFY
|
||||||
|
|
@ -286,22 +332,15 @@ internal sealed unsafe class DalamudIme : IDisposable, IServiceType
|
||||||
else
|
else
|
||||||
this.ReplaceCompositionString(hImc, (uint)args.LParam);
|
this.ReplaceCompositionString(hImc, (uint)args.LParam);
|
||||||
|
|
||||||
// Log.Verbose($"{nameof(WM.WM_IME_COMPOSITION)}({(nint)args.LParam:X}): {this.compositionString}");
|
|
||||||
args.SuppressWithValue(0);
|
args.SuppressWithValue(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM.WM_IME_ENDCOMPOSITION:
|
case WM.WM_IME_ENDCOMPOSITION:
|
||||||
// Log.Verbose($"{nameof(WM.WM_IME_ENDCOMPOSITION)}({(nint)args.WParam:X}, {(nint)args.LParam:X}): {this.compositionString}");
|
this.ClearState(hImc, false);
|
||||||
args.SuppressWithValue(0);
|
args.SuppressWithValue(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM.WM_IME_CONTROL:
|
case WM.WM_IME_CONTROL:
|
||||||
// Log.Verbose($"{nameof(WM.WM_IME_CONTROL)}({(nint)args.WParam:X}, {(nint)args.LParam:X}): {this.compositionString}");
|
|
||||||
args.SuppressWithValue(0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM.WM_IME_REQUEST:
|
case WM.WM_IME_REQUEST:
|
||||||
// Log.Verbose($"{nameof(WM.WM_IME_REQUEST)}({(nint)args.WParam:X}, {(nint)args.LParam:X}): {this.compositionString}");
|
|
||||||
args.SuppressWithValue(0);
|
args.SuppressWithValue(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -309,14 +348,9 @@ internal sealed unsafe class DalamudIme : IDisposable, IServiceType
|
||||||
// Hide candidate and composition windows.
|
// Hide candidate and composition windows.
|
||||||
args.LParam = (LPARAM)((nint)args.LParam & ~(ISC_SHOWUICOMPOSITIONWINDOW | 0xF));
|
args.LParam = (LPARAM)((nint)args.LParam & ~(ISC_SHOWUICOMPOSITIONWINDOW | 0xF));
|
||||||
|
|
||||||
// Log.Verbose($"{nameof(WM.WM_IME_SETCONTEXT)}({(nint)args.WParam:X}, {(nint)args.LParam:X}): {this.compositionString}");
|
|
||||||
args.SuppressWithDefault();
|
args.SuppressWithDefault();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM.WM_IME_NOTIFY:
|
|
||||||
// Log.Verbose($"{nameof(WM.WM_IME_NOTIFY)}({(nint)args.WParam:X}): {this.compositionString}");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM.WM_KEYDOWN when (int)args.WParam is
|
case WM.WM_KEYDOWN when (int)args.WParam is
|
||||||
VK.VK_TAB
|
VK.VK_TAB
|
||||||
or VK.VK_PRIOR
|
or VK.VK_PRIOR
|
||||||
|
|
@ -335,7 +369,11 @@ internal sealed unsafe class DalamudIme : IDisposable, IServiceType
|
||||||
}
|
}
|
||||||
|
|
||||||
this.UpdateCandidates(hImc);
|
this.UpdateCandidates(hImc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM.WM_KEYDOWN when (int)args.WParam is VK.VK_ESCAPE && this.candidateStrings.Count != 0:
|
||||||
|
this.ClearState(hImc);
|
||||||
|
args.SuppressWithDefault();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM.WM_LBUTTONDOWN:
|
case WM.WM_LBUTTONDOWN:
|
||||||
|
|
@ -344,15 +382,14 @@ internal sealed unsafe class DalamudIme : IDisposable, IServiceType
|
||||||
case WM.WM_XBUTTONDOWN:
|
case WM.WM_XBUTTONDOWN:
|
||||||
ImmNotifyIME(hImc, NI.NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
|
ImmNotifyIME(hImc, NI.NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// default:
|
|
||||||
// Log.Verbose($"{(WmNames.TryGetValue((int)args.Message, out var v) ? v : args.Message.ToString())}({(nint)args.WParam:X}, {(nint)args.LParam:X})");
|
|
||||||
// break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.UpdateInputLanguage(hImc);
|
if (args.Message != WM.WM_MOUSEMOVE)
|
||||||
if (this.inputModeIcon == (char)SeIconChar.ImeKoreanHangul)
|
{
|
||||||
this.UpdateCandidates(hImc);
|
this.UpdateInputLanguage(hImc);
|
||||||
|
if (this.inputModeIcon == (char)SeIconChar.ImeKoreanHangul)
|
||||||
|
this.UpdateCandidates(hImc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
@ -367,8 +404,6 @@ internal sealed unsafe class DalamudIme : IDisposable, IServiceType
|
||||||
var lang = GetKeyboardLayout(0);
|
var lang = GetKeyboardLayout(0);
|
||||||
var open = ImmGetOpenStatus(hImc) != false;
|
var open = ImmGetOpenStatus(hImc) != false;
|
||||||
|
|
||||||
// Log.Verbose($"{nameof(this.UpdateInputLanguage)}: conv={conv:X} sent={sent:X} open={open} lang={lang:X}");
|
|
||||||
|
|
||||||
var native = (conv & 1) != 0;
|
var native = (conv & 1) != 0;
|
||||||
var katakana = (conv & 2) != 0;
|
var katakana = (conv & 2) != 0;
|
||||||
var fullwidth = (conv & 8) != 0;
|
var fullwidth = (conv & 8) != 0;
|
||||||
|
|
@ -418,6 +453,10 @@ internal sealed unsafe class DalamudIme : IDisposable, IServiceType
|
||||||
? ImmGetCompositionString(hImc, GCS.GCS_RESULTSTR)
|
? ImmGetCompositionString(hImc, GCS.GCS_RESULTSTR)
|
||||||
: ImmGetCompositionString(hImc, GCS.GCS_COMPSTR);
|
: ImmGetCompositionString(hImc, GCS.GCS_COMPSTR);
|
||||||
|
|
||||||
|
#if IMEDEBUG
|
||||||
|
Log.Verbose($"{nameof(this.ReplaceCompositionString)}({newString})");
|
||||||
|
#endif
|
||||||
|
|
||||||
this.ReflectCharacterEncounters(newString);
|
this.ReflectCharacterEncounters(newString);
|
||||||
|
|
||||||
if (this.temporaryUndoSelection is not null)
|
if (this.temporaryUndoSelection is not null)
|
||||||
|
|
@ -436,8 +475,8 @@ internal sealed unsafe class DalamudIme : IDisposable, IServiceType
|
||||||
|
|
||||||
if (finalCommit)
|
if (finalCommit)
|
||||||
{
|
{
|
||||||
this.ClearState(hImc);
|
this.ClearState(hImc, false);
|
||||||
return;
|
newString = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.compositionString = newString;
|
this.compositionString = newString;
|
||||||
|
|
@ -471,17 +510,21 @@ internal sealed unsafe class DalamudIme : IDisposable, IServiceType
|
||||||
this.UpdateCandidates(hImc);
|
this.UpdateCandidates(hImc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearState(HIMC hImc)
|
private void ClearState(HIMC hImc, bool invokeCancel = true)
|
||||||
{
|
{
|
||||||
this.compositionString = string.Empty;
|
this.compositionString = string.Empty;
|
||||||
this.partialConversionFrom = this.partialConversionTo = 0;
|
this.partialConversionFrom = this.partialConversionTo = 0;
|
||||||
this.compositionCursorOffset = 0;
|
this.compositionCursorOffset = 0;
|
||||||
this.temporaryUndoSelection = null;
|
this.temporaryUndoSelection = null;
|
||||||
TextState->Stb.SelectStart = TextState->Stb.Cursor = TextState->Stb.SelectEnd;
|
TextState->Stb.SelectStart = TextState->Stb.Cursor = TextState->Stb.SelectEnd;
|
||||||
ImmNotifyIME(hImc, NI.NI_COMPOSITIONSTR, CPS_CANCEL, 0);
|
this.candidateStrings.Clear();
|
||||||
this.UpdateCandidates(default);
|
this.immCandNative = default;
|
||||||
|
if (invokeCancel)
|
||||||
|
ImmNotifyIME(hImc, NI.NI_COMPOSITIONSTR, CPS_CANCEL, 0);
|
||||||
|
|
||||||
// Log.Information($"{nameof(this.ClearState)}");
|
#if IMEDEBUG
|
||||||
|
Log.Information($"{nameof(this.ClearState)}({invokeCancel})");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateCandidates(HIMC hImc)
|
private void UpdateCandidates(HIMC hImc)
|
||||||
|
|
@ -932,4 +975,71 @@ internal sealed unsafe class DalamudIme : IDisposable, IServiceType
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if IMEDEBUG
|
||||||
|
private static class ImeDebug
|
||||||
|
{
|
||||||
|
private static readonly (int Value, string Name)[] GcsFields =
|
||||||
|
{
|
||||||
|
(GCS.GCS_COMPREADSTR, nameof(GCS.GCS_COMPREADSTR)),
|
||||||
|
(GCS.GCS_COMPREADATTR, nameof(GCS.GCS_COMPREADATTR)),
|
||||||
|
(GCS.GCS_COMPREADCLAUSE, nameof(GCS.GCS_COMPREADCLAUSE)),
|
||||||
|
(GCS.GCS_COMPSTR, nameof(GCS.GCS_COMPSTR)),
|
||||||
|
(GCS.GCS_COMPATTR, nameof(GCS.GCS_COMPATTR)),
|
||||||
|
(GCS.GCS_COMPCLAUSE, nameof(GCS.GCS_COMPCLAUSE)),
|
||||||
|
(GCS.GCS_CURSORPOS, nameof(GCS.GCS_CURSORPOS)),
|
||||||
|
(GCS.GCS_DELTASTART, nameof(GCS.GCS_DELTASTART)),
|
||||||
|
(GCS.GCS_RESULTREADSTR, nameof(GCS.GCS_RESULTREADSTR)),
|
||||||
|
(GCS.GCS_RESULTREADCLAUSE, nameof(GCS.GCS_RESULTREADCLAUSE)),
|
||||||
|
(GCS.GCS_RESULTSTR, nameof(GCS.GCS_RESULTSTR)),
|
||||||
|
(GCS.GCS_RESULTCLAUSE, nameof(GCS.GCS_RESULTCLAUSE)),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly IReadOnlyDictionary<int, string> ImnFields =
|
||||||
|
typeof(IMN)
|
||||||
|
.GetFields(BindingFlags.Static | BindingFlags.Public)
|
||||||
|
.Where(x => x.IsLiteral)
|
||||||
|
.ToDictionary(x => (int)x.GetRawConstantValue()!, x => x.Name);
|
||||||
|
|
||||||
|
public static string GcsName(int val)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
foreach (var (value, name) in GcsFields)
|
||||||
|
{
|
||||||
|
if ((val & value) != 0)
|
||||||
|
{
|
||||||
|
if (sb.Length != 0)
|
||||||
|
sb.Append(" | ");
|
||||||
|
sb.Append(name);
|
||||||
|
val &= ~value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val != 0)
|
||||||
|
{
|
||||||
|
if (sb.Length != 0)
|
||||||
|
sb.Append(" | ");
|
||||||
|
sb.Append($"0x{val:X}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ImcName(int val) => ImnFields.TryGetValue(val, out var name) ? name : $"0x{val:X}";
|
||||||
|
|
||||||
|
public static string ImnName(int val) => ImnFields.TryGetValue(val, out var name) ? name : $"0x{val:X}";
|
||||||
|
|
||||||
|
public static string ImrName(int val) => val switch
|
||||||
|
{
|
||||||
|
IMR_CANDIDATEWINDOW => nameof(IMR_CANDIDATEWINDOW),
|
||||||
|
IMR_COMPOSITIONFONT => nameof(IMR_COMPOSITIONFONT),
|
||||||
|
IMR_COMPOSITIONWINDOW => nameof(IMR_COMPOSITIONWINDOW),
|
||||||
|
IMR_CONFIRMRECONVERTSTRING => nameof(IMR_CONFIRMRECONVERTSTRING),
|
||||||
|
IMR_DOCUMENTFEED => nameof(IMR_DOCUMENTFEED),
|
||||||
|
IMR_QUERYCHARPOSITION => nameof(IMR_QUERYCHARPOSITION),
|
||||||
|
IMR_RECONVERTSTRING => nameof(IMR_RECONVERTSTRING),
|
||||||
|
_ => $"0x{val:X}",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue