Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Odd experience typing Japanese text on Windows: Removing the first unconverted hiragana effectively requires TWO Backspace input #18021

Closed
MineCake147E opened this issue Jan 22, 2025 · 1 comment · Fixed by #18034
Labels

Comments

@MineCake147E
Copy link
Contributor

Describe the bug

On most apps, removing all unconverted hiraganas by pressing Backspace cancels conversion entirely and clears all unconverted hiraganas correctly.
In Avalonia on Windows, removal of all unconverted hiraganas is somehow getting treated as input completion of the first hiragana, effectively needing additional Backspace input to remove that erroneously 'completed' hiragana.

Here's the video explaining the issue using the same reproduction app with #18013 . First, I completed typing テスト and cleared it. However, when I tried to delete all the characters after typing てすと, for some reason it remained as if the was completed, and I had to press backspace again.

AvaloniaInputMethod.2025-01-22.18-47-01.mp4

To Reproduce

  1. Create an Avalonia project with Community Toolkit and Compiled Bindings
  2. Upgrade TargetFramework to net9.0-* in all projects
  3. Edit the MainView.axaml as shown below
  4. Edit the MainViewModel.cs as shown below
  5. Start debugging with physical Windows device with Google Japanese Input installed (Microsoft IME also reproduces this problem)
  6. Type irohanihoheto then hit Backspace 7 times to remove the いろはにほへと shown there, and see what happens

MainView.axaml

<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:vm="clr-namespace:AvaloniaInputMethod.ViewModels"
             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
             x:Class="AvaloniaInputMethod.Views.MainView"
             x:DataType="vm:MainViewModel">
  <Design.DataContext>
    <!-- This only sets the DataContext for the previewer in an IDE,
         to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
    <vm:MainViewModel />
  </Design.DataContext>
  <DockPanel>
    <Border DockPanel.Dock="Top" Margin="2" BorderBrush="{DynamicResource TextControlBorderBrush}" BorderThickness="1" CornerRadius="2">
      <TextBlock Text="{Binding Input, Mode=OneWay}"/>
    </Border>
    <TextBox Text="{Binding Input, Mode=TwoWay}" AcceptsReturn="True" Margin="2"/>
  </DockPanel>
</UserControl>

MainViewModel.cs

using CommunityToolkit.Mvvm.ComponentModel;

namespace AvaloniaInputMethod.ViewModels;

public partial class MainViewModel : ViewModelBase
{
    [ObservableProperty]
    private string input = "";
}

Expected behavior

doesn't show after removing unconverted いろはにほへと

Avalonia version

11.2.3

OS

Windows

Additional context

  • PC: Custom built PC
    • OS: Windows 11 Home 23H2 (22631.4751)
    • CPU: Intel(R) Xeon(R) w5-2455X 3.19 GHz
    • RAM: 32 GB DDR5 ECC RDIMM
    • Graphics: NVIDIA GeForce GTX1060(6 GB)
    • Storage:
      • OS(C:) : WD_BLACK SN770 1TB PCIe 4.0 NVMe M.2 SSD
      • DATA (D:) : Western Digital WDC WD10EZEX-22MFCA0 1000.2 GB 7200RPM SATA HDD
      • WORKSPACE (E:) : Seagate ST1000DM003-1ER162 1000.2 GB 7200RPM SATA HDD
@MineCake147E
Copy link
Contributor Author

I investigated a little bit about IME's cancel behavior.
It turns out that AppWndProc is receiving WM_IME_COMPOSITION with lParam set to 0 after I do the following:

  • Removing the entire composition string by pressing Backspace
  • Pressing Escape while the composition string remains

In VS Code, in both cases, it deleted the entire composition string without entering anything.
But Avalonia's TextBox kept the whole composition string. And when it receives WM_IME_ENDCOMPOSITION, Imm32InputMethod.HandleCompositionEnd checks if Imm32InputMethod.Composition is either null or empty, while it still contains the composition string. As a result, it ends up executing _parent.Input(e); while retaining the mistreated composition string.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
1 participant