Bug 156443 - Windows: alt+numpad doesn't work for Unicode decimal codes, like in WordPad/Word
Summary: Windows: alt+numpad doesn't work for Unicode decimal codes, like in WordPad/Word
Status: RESOLVED FIXED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: LibreOffice (show other bugs)
Version:
(earliest affected)
unspecified
Hardware: All Windows (All)
: medium enhancement
Assignee: Mike Kaganski
URL:
Whiteboard: target:24.8.0 target:24.2.1
Keywords:
: 59400 (view as bug list)
Depends on: 158112
Blocks:
  Show dependency treegraph
 
Reported: 2023-07-24 13:35 UTC by Mike Kaganski
Modified: 2024-04-04 13:57 UTC (History)
9 users (show)

See Also:
Crash report or crash signature:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mike Kaganski 2023-07-24 13:35:22 UTC
As described in Wikipedia [1], there is a way to use Alt + NumPad on Windows to input Unicode characters. E.g., holding [Alt] and typing [3],[0],[4] on the numpad, and releasing [Alt], produces "İ" (LATIN CAPITAL LETTER I WITH DOT ABOVE, U+0130; decimal 304) in WordPad and in Word.

But in LibreOffice (and in notepad.exe), this produces "0", which is U+0030, or decimal 48, which is 304 mod 256.

Despite we have a dedicated Alt+X function, converting hexadecimal codes to characters and back, users still expect the Alt + numpad combination to work, because it is mentioned in multiple places (e.g., fileformat.info [2] has a "How to type in Microsoft Windows" entry), and questions arise, when this doesn't work [3].

The keypresses described above produce this sequence of Windows messages received by ImplSalYield in vcl/win/app/salinst.cxx:

  WM_SYSKEYDOWN (VK_MENU with scancode 38)
  WM_SYSKEYDOWN (VK_NUMPAD3 with scancode 51)
  WM_SYSKEYUP (VK_NUMPAD3 with scancode 51)
  WM_SYSKEYDOWN (VK_NUMPAD0 with scancode 52)
  WM_SYSKEYUP (VK_NUMPAD0 with scancode 52)
  WM_SYSKEYDOWN (VK_NUMPAD4 with scancode 4B)
  WM_SYSKEYUP (VK_NUMPAD4 with scancode 4B)
  WM_KEYUP (VK_MENU with scancode 38)
  WM_CHAR ('0' with scancode 38)

Note that the last WM_CHAR is produced by TranslateMessage from the previous Alt input, and it has the value that we use in the program (and which is bad). This event sequence is identical also for WordPad, so there is no difference here, only in the handling of the messages themselves.

The processing of the final WM_CHAR happens in ImplHandleKeyMsg in vcl/win/window/salframe.cxx; there is a section starting with a comment telling "only "free flying" WM_CHAR messages arrive here, that are created by typing an ALT-NUMPAD combination".

It seems clear, that Windows itself doesn't provide the Unicode WM_CHAR data for Alt input (even for Unicode windows, which LibreOffice windows are), and WordPad / Word likely handle the SYSKEY* messages themselves to handle such input. If we want to also handle it, we should do the following:

1. Log the SYSKEYDOWN/SYSKEYUP messages after initial Alt press SYSKEYDOWN event, and if they are all from numpad, store their sequence (and drop it if anything from non-numpad arrives).
2. When Alt key's WM_KEYUP arrives, analyze the stored sequence, and decide if it's Unicode (i.e., if it starts with [0] or is greater than 255) or not.
3. If it's non-Unicode, just drop the sequence, and process the following WM_CHAR as before.
4. If it was Unicode, then ignore the following WM_CHAR (having the scancode of Alt), and instead, send an internal event with the proper Unicode character.

It is likely that ImplHandleKeyMsg is the best candidate for the change.

Note also, that there is a "EnableHexNumpad" Windows registry setting that allows hex Alt entry [4]; the fix might also handle that (or a follow-up enhancement could be filed for that).

[1] https://en.wikipedia.org/wiki/Unicode_input#Decimal_input
[2] https://www.fileformat.info/info/unicode/char/0130/index.htm
[3] https://ask.libreoffice.org/t/lo-witer-strange-little-problem-capital-i-with-a-dot-on-top/93756/
[4] https://superuser.com/a/59458
Comment 1 V Stuart Foote 2023-11-24 19:09:13 UTC
+1
Comment 2 Mike Kaganski 2023-12-20 14:23:25 UTC
This depends on bug 158112, because until the conflict with shortcuts is resolved, implementing the proposal is not realistic.
Comment 3 V Stuart Foote 2023-12-20 19:03:17 UTC
@Mike, isn't the trigger on Windows the Keyup release of the <Alt> key.

So we could isolate and continue to use the <Alt>+[1-9] shortcuts for the SB decks, exactly as you suggest?
Comment 4 libretist 2023-12-20 22:49:12 UTC
How would your proposed method distinguish between ALT+7 as a LibreOffice shortcut and ALT+7 as input for the bullet point sign "•" in Windows ?
Comment 5 libretist 2023-12-21 12:21:16 UTC Comment hidden (off-topic)
Comment 6 Mike Kaganski 2023-12-21 12:34:55 UTC Comment hidden (off-topic)
Comment 7 libretist 2023-12-21 20:59:25 UTC Comment hidden (off-topic)
Comment 8 Mike Kaganski 2023-12-22 05:48:30 UTC
(In reply to libretist from comment #7)

The proposal here is based on the status *prior* to bug 158112. You may recall, that you wrote bug 158786 as a "regression": before the assignment of Alt+Number to sidebar panels, you could normally use the ALT+168 combination, and get what you expected.

As explained in comment 0, the *combinations starting with 0 or greater than 255* weren't processed correctly. Values below 256 were processed using Windows WM_CHAR message, which contains a resulting character value, but only truncated. So the whole text there discussed how to enable *also* greater values.

Then comment 3 (not mine) could confuse people, because it suggested this proposal as a "solution" to bug 158112 (which is it not, and can't be). As you noted in bug 158112 comment 22, even Alt+single_digit is a useful special character combination.

But in any case, before writing things like "Many characters ... are not handled by your method", one needs to make sure they understand what they object to.
Comment 9 V Stuart Foote 2023-12-22 12:57:55 UTC
But don't the VK_NUMPAD[0-9] emit different scancodes to the VK_[0-9]? Hex values (and decimal) of 0x60 -- 0x69 (96-105), 0x30 -- 0x39 (48-57) respectively.  [1][2]

Also the loworder (1-254) "OEM" and 4-digit "ANSI" (dec 0032-0255 matching Unicode BMP) MS Alt keys *only* work for the NUMPAD keys?

So on Windows builds the SB shortcuts in fact could still use the <Alt>+[1-9] and leave the Alt+NUMPAD[0-9] for os/DE use.

The 'EnableHexNumpad' flavor ALT codes maybe needing a bit more handling, but by that point our <Alt>+x toggle already services Unicode centric users.

=-ref-=
[1] https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tvtt/261ddfb0-ce10-4380-9b7a-4b50f482b8ec
[2] https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
Comment 10 Mike Kaganski 2023-12-22 13:12:34 UTC
(In reply to V Stuart Foote from comment #9)
> But don't the VK_NUMPAD[0-9] emit different scancodes to the VK_[0-9]? Hex
> values (and decimal) of 0x60 -- 0x69 (96-105), 0x30 -- 0x39 (48-57)
> respectively.  [1][2]

Indeed. We are able to disambiguate ~all keys on keyboard. If wanted, we can also keep the numpad numbers for Alt-extended characters, and other numbers for shortcuts. This still requires fixing bug 158112 (e.g., exactly this way: making Alt+Number shortcuts only work for non-numpad numbers) first, as I explained in comment 3.

> The 'EnableHexNumpad' flavor ALT codes maybe needing a bit more handling,
> but by that point our <Alt>+x toggle already services Unicode centric users.

EnableHexNumpad may be a separate issue, if needed. I mentioned it here, but with a note that "a follow-up enhancement could be filed for that". So it may be excluded from consideration here.

However, I would think that Alt+NonNumpadNumber shortcut would still be confusing. Also, listing the Alt+Number in customization provokes for using it; and people who will try will *mostly* complain that it doesn't work: they would expect numpad numbers to do what they expect from the shortcut, and see it doesn't (because it would be used for Alt+Numpad Number extended character function).

I am strongly in favor of removing Alt+Number as an assignable key combination on Windows, completely.
Comment 11 V Stuart Foote 2023-12-22 15:03:39 UTC
(In reply to Mike Kaganski from comment #10)

> I am strongly in favor of removing Alt+Number as an assignable key
> combination on Windows, completely.

OK, not opposed, other than normal cross-platform documentation issues.

So back to resolving bug 158112 and my suggestion about returning to the <Ctrl><Alt>+[1-9], but to avoid bug 151059 by adjusting to handling for <AltGr> <==> <Ctrl><Alt> needed for os/DE VK_MENU mapping when missing <AltGr> keyboards. 

Distinguishing between l-Alt and r-Alt modifier key scancodes could be an approach on several issues. But treacherous as we'd already tried similar for bug 95761 (Jurgen's work) [1] to normalize the <Alt>+[x|c]Unicode toggle [2] and that had gotten messy and had to be reverted for bug 97908.

=-ref-=
[1] https://gerrit.libreoffice.org/19923
[2] Justin's implementation on bug 73691
Comment 12 libretist 2023-12-22 15:18:01 UTC
(In reply to Mike Kaganski from comment #8)
sorry for my misunderstanding
Comment 13 Mike Kaganski 2024-01-10 14:14:39 UTC
https://gerrit.libreoffice.org/c/core/+/161891

Since it affects a number of issues, I decided to handle this myself.
This will also fix tdf#159079.
Also, this will fix tdf#158112 - by completely disabling Alt+NumPad shortcuts, allowing only Alt+Numbers from main keyboard area. Basically, what V Stuart Foote suggested (even though I disliked the idea initially).

Please shout if the last point (disabling Alt+NumPad) is concerning.
Comment 14 Commit Notification 2024-01-10 16:39:49 UTC
Mike Kaganski committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/core/commit/772da0f1aa6891a0b31d45d99a5978c65ed24e34

tdf#156443, tdf#159079, tdf#158112: support Windows Alt codes >=256

It will be available in 24.8.0.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 15 V Stuart Foote 2024-01-10 20:01:21 UTC
(In reply to Mike Kaganski from comment #13)
> https://gerrit.libreoffice.org/c/core/+/161891
> 
> Since it affects a number of issues, I decided to handle this myself.
> This will also fix tdf#159079.
> Also, this will fix tdf#158112 - by completely disabling Alt+NumPad
> shortcuts, allowing only Alt+Numbers from main keyboard area. Basically,
> what V Stuart Foote suggested (even though I disliked the idea initially).
> 
> Please shout if the last point (disabling Alt+NumPad) is concerning.

On track, but could be an accessibility issue with the Numlock override of the NumPad scancodes. 

The NVDA assistive technology extensively uses the NumPad for program controls. If LO interferes with that, it could be a major annoyance for that group of users.

Michael W., any perspective?
Comment 16 Michael Weghorn 2024-01-11 08:50:55 UTC
(In reply to V Stuart Foote from comment #15)
> The NVDA assistive technology extensively uses the NumPad for program
> controls. If LO interferes with that, it could be a major annoyance for that
> group of users.
> 
> Michael W., any perspective?

I don't know the details of how this works on Windows, but I think that screen readers intercept keyboard events *before* they get sent to the application, while Mike's change from a quick look only changes the handling inside of LO, in which case I wouldn't expect any problems.

I won't have access to a keyboard with a Num block before Tuesday, but if somebody has, a quick test whether e.g. the NVDA+numpad5 command to report the current object still works might be useful when the desktop layout is used for NVDA ("Preferences" -> "Settings" -> "Keyboard" -> "Keyboard layout").
Doc: https://www.nvaccess.org/files/nvda/documentation/userGuide.html#ObjectNavigation

CC'ing Quentin, who might have further insights regarding NVDA.
Comment 17 V Stuart Foote 2024-01-11 15:09:31 UTC
(In reply to Michael Weghorn from comment #16)

> I won't have access to a keyboard with a Num block before Tuesday, but if
> somebody has, a quick test whether e.g. the NVDA+numpad5 command to report
> the current object still works might be useful when the desktop layout is
> used for NVDA ("Preferences" -> "Settings" -> "Keyboard" -> "Keyboard
> layout").

So seems to be no issues, the default NVDA key (Numpad 'Ins' key) continues to function.

With default NVDA key of the numpad Insert, "NVDA+n" and "NVDA+<NumPad_5>" both behaved with expected NVDA responses.

=-Testing-=
Win10 (22H2 19045) 

NVDA Version: 2023.3 (2023.3.0.29780)

With TB-78 nightly 20230111
Version: 24.8.0.0.alpha0+ (X86_64) / LibreOffice Community
Build ID: 3cb1ed4339fc9aec414c0f112a69705a7a4d9cc6
CPU threads: 8; OS: Windows 10.0 Build 19045; UI render: Skia/Vulkan; VCL: win
Locale: en-US (en_US); UI: en-US
Calc: CL threaded
Comment 18 Michael Weghorn 2024-01-12 09:24:08 UTC
(In reply to V Stuart Foote from comment #17)
> So seems to be no issues, the default NVDA key (Numpad 'Ins' key) continues
> to function.
> 
> With default NVDA key of the numpad Insert, "NVDA+n" and "NVDA+<NumPad_5>"
> both behaved with expected NVDA responses.

Great, thanks for testing! All should be fine then from what I can say.
Comment 19 Commit Notification 2024-01-12 18:31:38 UTC
Mike Kaganski committed a patch related to this issue.
It has been pushed to "libreoffice-24-2":

https://git.libreoffice.org/core/commit/45023ae9619cdc4332afb8f743d1695a23e8d866

tdf#156443, tdf#159079, tdf#158112: support Windows Alt codes >=256

It will be available in 24.2.1.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 20 Buovjaga 2024-02-10 13:39:09 UTC
*** Bug 59400 has been marked as a duplicate of this bug. ***