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

ReceivedCharacter no longer emitted on Windows for Alt+key since PR#2445 #2504

Closed
ilya-bobyr opened this issue Sep 28, 2022 · 8 comments
Closed
Labels
C - needs discussion Direction must be ironed out DS - windows S - platform parity Unintended platform differences

Comments

@ilya-bobyr
Copy link

In #2445 a change was made, affecting only Windows, to spot sending ReceivedCharacter in response to WM_SYSCHAR messages, or Alt+key combination.

This creates a discrepancy between Windows and other platforms. As on other platforms, ReceivedCharacter is still sent when Alt+b is pressed, for example.

Alacritty is one of the applications that use winit and is negatively affected by this change.
See this issue for Alacritty specific discussion: alacritty/alacritty#6356

Was this intentional that Alt+key is no longer sending ReceivedCharacter and other platforms will be updated similarly, or was it an accident?

@msiglreith msiglreith added DS - windows C - needs discussion Direction must be ironed out S - platform parity Unintended platform differences labels Sep 28, 2022
@msiglreith
Copy link
Member

Yes this was kind of intentional based on the Windows documentation and how these Alt + <Key> combinations are processed on Windows. In particular, the following quote would speak against emitting a ReceivedChar in this scenario:

The WM_SYSCHAR message indicates a system character. As with WM_SYSKEYDOWN, you should generally pass this message directly to DefWindowProc. Otherwise, you may interfere with standard system commands. In particular, do not treat WM_SYSCHAR as text that the user has typed.

@kchibisov
Copy link
Member

I think the right way would be to revert that for now? Given that it's causing portability issues and causing issues downstream? The right fix for that would be a keyboard v2 API?

What do you think @msiglreith ?

@msiglreith
Copy link
Member

I mean we can forward the WM_SYSCHAR stuff but there seems no good solution in the long run even to expose a ReceivedChar for these. The option I currently see are:

  1. Don't support system keybinds (basically the previous behavior)
  2. Support system keybinds and don't emit ReceivedChar (e.g Alt + Space will open the menu and not print )
  3. System keybinds and emit ReceivedChar - emitting two different things for one keybind
  4. Expose some flag for the user to decide..

@kchibisov
Copy link
Member

The issue is that we need ReceivedChar downstream. It'll all change with keyboard v2, but I'm not sure it's close.

Right now I don't see a way to fix the issue in alacritty, since we need characters to handle alt bindings.

@msiglreith
Copy link
Member

Created a workaround for now in #2505 based on the 3rd approach - please verify if this is works for alacritty

@ajtribick
Copy link
Contributor

Another possibility is to intercept WM_MENUCHAR - this will pick up anything that isn't a system keypress.

@ilya-bobyr
Copy link
Author

Looking at #2505 I started wondering if it might be possible to provide the necessary customization without a larger change in the API.

On Windows, as Alt+key may have special meaning, it is indeed reasonable to skip ReceivedCharacter() for some applications.
But when an application does want to process Alt+key consistently on all platforms, it would need to have platform specific code, should winit behave differently on different platforms.

I am not familiar with winit, nor the keyboard v2 proposal.
But I was wondering if it might be possible to reconstruct ReceivedCharacter() and/or the DefWindowProcW(window, msg, wparam, lparam) call based on the KeyboardInput events that are still delivered.
If it is the case, winit could provide two functions: one that reconstructs ReceivedCharacter() and another that calls DefWindowProcW(window, msg, wparam, lparam).
An application would need to call one, call the other, call both, or none; in order to explicitly select desired behavior for, say Alt+Space: deliver Space as ReceivedCharacter(), open the window menu, do both or do neither.
For non-Windows platforms there are two options:

  1. Alt+key always generates ReceivedCharacter() and both functions do nothing.
  2. Alt+key never generates ReceivedCharacter(), the first function sends ReceivedCharacter(), and the second function does nothing.

Not sure if this is really the best API design. It still needs a breaking change, as #2505 as proposed will actually both deliver ReceivedCharacter() and open the window menu, for Alt+Space. And it can not be undone. These “adapter functions” would require the default to not do anything.
And if a breaking change is required, maybe you already have a better alternative in the pipeline.

@ilya-bobyr
Copy link
Author

Thank you for the fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C - needs discussion Direction must be ironed out DS - windows S - platform parity Unintended platform differences
Development

No branches or pull requests

4 participants