keymanapp / keyman

Keyman cross platform input methods system running on Android, iOS, Linux, macOS, Windows and mobile and desktop web
https://keyman.com/
Other
391 stars 108 forks source link

Label tracks do not accept input from Keyman Desktop in Audacity 2.1.2 and later #523

Open mcdurdin opened 6 years ago

mcdurdin commented 6 years ago

Initial report on community.software.sil.org.

Recent versions of Audacity, from 2.1.2 onward, appear to bypass Keyman entirely for input. Looking at the Audacity 2.1.2 release notes, the major change made was an update to wxWidgets 3.0.2.

So I suspect that we should be looking at wxWidgets 3.0 for this compat issues. In 3.0.0 they merged ANSI and Unicode support and my stab-in-the-dark guess is that they may have inadvertently turned their windows into ANSI windows in the process. Or something like that, I hope, which could be easy to resolve.

mcdurdin commented 6 years ago

I've just installed 2.2.1 here and tested. I can reproduce the issue, e.g. in a Label track. The issue doesn't arise in the Metadata window. A high-level diagnostic showed that Audacity is capturing keystrokes before Keyman sees them and doing an internal translation to characters using Windows API calls. This is not an uncommon pattern for cross-platform projects but it cannot duplicate the Windows internal character translation, even for Windows keyboards, 100% perfectly. So it's the wrong way to go...

Now digging deeper in source code.

mcdurdin commented 6 years ago

Okay. So the issue with label track edits is in Audacity. Label tracks don't use a standard Windows or wxWidgets edit control, and have instead a bunch of code to implement a basic text edit field. The root issue is in this code in CommandManager.cpp:

   // Convert the key down event to a unicode string.
   wxString GetUnicodeString(const wxKeyEvent & event)
   {
      wxString chars;

#if defined(__WXMSW__)

      BYTE ks[256];
      GetKeyboardState(ks);
      WCHAR ucode[256];
      int res = ToUnicode(event.GetRawKeyCode(), 0, ks, ucode, 256, 0);
      if (res >= 1)
      {
         chars.Append(ucode, res);
      }

Audacity is handling WM_KEYDOWN events (these are wrapped in wxKeyEvent objects), and then calling ToUnicode to convert key events to Unicode characters. This isn't the right way to get character input on Windows. The ToUnicode function doesn't cover all Windows input cases, even for standard Windows keyboards and IMEs. Instead, Audacity should be accepting WM_CHAR events and processing these (MSDN).

From the description in http://bugzilla.audacityteam.org/show_bug.cgi?id=1778, it sounds like similar issues are arising in macOS. See also discussion in http://forum.audacityteam.org/viewtopic.php?p=319325.

mcdurdin commented 6 months ago

https://github.com/audacity/audacity/issues/5163 is also same root cause I believe