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

Update InputEventKey doc: Clarify behavior when setting event properties #84836

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jsjtxietian
Copy link
Contributor

Fixes #84731

Suggestions are welcomed as I'm not a native English speaker.

@timothyqiu
Copy link
Member

I don't think this explains the problem. You're just describing the nature of all properties to be set to their default value on creation, which is true for any Variant, not just InputEventKey.

The core of #84731 is assuming setting one of keycode, physical_keycode, and unicode automatically updates other fields.

@jsjtxietian
Copy link
Contributor Author

setting one of keycode, physical_keycode, and unicode automatically updates other fields

Or it's just the name confuses them, a little hard to clarify though.

@AThousandShips
Copy link
Member

Or it's just the name confuses them

Not really, the confusion is that people assume they are linked and update together, and aren't separate properties

@akien-mga
Copy link
Member

akien-mga commented Nov 13, 2023

I think adding docs here is useful, as the behavior is far from obvious. It's not an oversight that only one of keycode or physical_keycode is non-zero, it's actually how InputEventKey knows whether it's a physical or not physical event.

But to fix #84731 itself, I would add documentation to OS.get_keycode_string(), to point out this difference between keycode and physical_keycode.

@akien-mga akien-mga requested a review from bruvzg November 13, 2023 10:57
Copy link
Member

@bruvzg bruvzg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Event mappings should have only one of the [member keycode], [member physical_keycode], or [member unicode] set.

Seems a bit excessive, this part already describes the same behavior.

@timothyqiu
Copy link
Member

I would add documentation to OS.get_keycode_string(), to point out this difference between keycode and physical_keycode.

OS.get_keycode_string() simply maps the Key enum into String, it has no concept of keycode and physical_keycode.

Another possible cause is that the 4.1.3 documentation for physical_keycode also says you should use keycode. This is already fixed in 4.2.

<member name="physical_keycode" type="int" setter="set_physical_keycode" getter="get_physical_keycode" enum="Key" default="0">
Represents the physical location of a key on the 101/102-key US QWERTY keyboard, which corresponds to one of the [enum Key] constants.
To get a human-readable representation of the [InputEventKey], use [code]OS.get_keycode_string(event.keycode)[/code] where [code]event[/code] is the [InputEventKey].
</member>

@akien-mga
Copy link
Member

I would add documentation to OS.get_keycode_string(), to point out this difference between keycode and physical_keycode.

OS.get_keycode_string() simply maps the Key enum into String, it has no concept of keycode and physical_keycode.

My point is that OS.get_keycode_string() is used with an int, and we don't tell users what that int should be explictly enough. If they have an event, and want the string for that event's key code, they need to use the right property based on the type of key code their event uses.

And the event is one they receive and they don't know ahead of time if it's physical or not, they basically need to reimplement the internal logic we use:

OS.get_keycode_string(event.physical_keycode if event.keycode == KEY_NONE else event.keycode)

which doesn't feel very satisfactory as API design, but at least this can be documented.

@jsjtxietian
Copy link
Contributor Author

jsjtxietian commented Nov 13, 2023

And the event is one they receive and they don't know ahead of time if it's physical or not, they basically need to reimplement the internal logic we use:

I do feel a little curious about this, why we have to store all three fields together instead of a tagged union or something like a variant to represent a InputKeyEvent, is there any corner cases that we need consider?

@AThousandShips
Copy link
Member

Because we don't usually do that and it's not necessary simple or stable to do so I'd say

@timothyqiu
Copy link
Member

timothyqiu commented Nov 13, 2023

And the event is one they receive and they don't know ahead of time if it's physical or not

They should know what they want to get. Physical keycode and keycode are in different domains. A physical "E" and a regular "E" are two different keys.

#84731 can only be handled reasonably in 4.2 via the new API:

OS.get_keycode_string(DisplayServer.keyboard_get_keycode_from_physical(e.physical_keycode))

And this is already documented in InputEventKey.

i.e. The issue is not a miss use of OS.get_keycode_string(), but a miss understanding of physical key and how related fields in InputEventKey are filled.

@akien-mga
Copy link
Member

Right, see also #82092. OS.get_keycode_string() description should likely advise users to check the description of InputEventKey.physical_keycode.

@jsjtxietian jsjtxietian marked this pull request as draft November 14, 2023 02:12
@jsjtxietian jsjtxietian marked this pull request as ready for review November 14, 2023 06:44
@jsjtxietian
Copy link
Contributor Author

They should know what they want to get. Physical keycode and keycode are in different domains.

If we don't need to store keycode and phyiscal keycode simultaneously, I believe this adds more weight to my initial thought of use a tagged union to store all these fields, in this way we can print some warning when user try to access the incorrect field. But I suspect it will break compatibility, the public interface doesn't have to change, but the serialized format will change.

@AThousandShips
Copy link
Member

AThousandShips commented Nov 15, 2023

It would require a lot of potentially fragile code to access and update the data, I'd say it's not worth it for a little data savings (you'd save at most one 32 bit value, as the flag for which type is stored would be aligned, so you'd at most save one 32 bit value)

@jsjtxietian
Copy link
Contributor Author

jsjtxietian commented Nov 15, 2023

Not for data saving, but for prevent get the wrong data. Maybe add a tag will do the same, but as you said, it is more work compared to gain. Should be designed from day 1.

@AThousandShips AThousandShips modified the milestones: 4.3, 4.4 Jul 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

OS.get_keycode_string() returns empty string
5 participants