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

Change: Make Command a valid modifier on OS-X #759

Merged
merged 1 commit into from
Jul 6, 2018

Conversation

leezer3
Copy link
Contributor

@leezer3 leezer3 commented May 24, 2018

Purpose of this PR

  • Adds the Command key to be a valid key modifer.
  • OS-X native window only.

Testing status

  • Untested- I've got no physical hardware, but assuming the NSEventModifierMask for Command is correct it's a simple change. See below.

Comments

  • This is Mac native platform specific only. This may make it too narrow to be merged into the main library, but on Mac, the Command modifier is the standard, and hence what users expect......

#757

@leezer3
Copy link
Contributor Author

leezer3 commented May 24, 2018

Hmm, just thought of a (mild) flaw in this :/
https://github.com/opentk/opentk/blob/develop/src/OpenTK/Input/Key.cs
Our key enum contains no definition for the Command key. As we're directly pulling the flags when one or more keys other than Command are pressed this doesn't (or at least shouldn't) matter.
However, when the command key is pressed on it's own, it'll be mapped here https://github.com/opentk/opentk/blob/develop/src/OpenTK/Platform/MacOS/MacOSKeyMap.cs#L243 to the Left Windows key.

Now, the obvious answer to that is just to add it to the enum, but I don't particularly like adding something at the start of the enum (Within the existing modifiers section) when it'll be a nightmare to check that our codebase isn't using the int representation for a key somewhere, let alone what third parties may or may not be doing......

Need some input from the maintainers here:
It's easy enough for me to add the enum value and do some basic testing on Windows and Linux, but this is an area where an edge case can easily explode on us.
So, is this worth doing (IMHO yes), and how do we go about it?

@leezer3
Copy link
Contributor Author

leezer3 commented May 25, 2018

The second commit adds the Command key to the enum, and actually makes this work.

Still need some maintainer input as to whether this is the best route mind :)

Testing status:

  • OS-X: High Sierra VM, standard Windows keyboard (Logitech) appears to return all keys correctly, including the new Command key.
  • Windows: All keys appear to work correctly.

Still concerned about any edge cases though. Whilst I can't think of any off the top of my head, the Key enum is used everywhere in the keyboard handling, and is a perfect candidate for biting us.
Need some other people to test this!

@Nihlus
Copy link
Contributor

Nihlus commented Jul 3, 2018

Thank you for you contribution! Currently, the develop branch is frozen while we work on the 4.0 release, and we are not accepting pull requests to it. All current pull requests should be based on that branch, or should be updated to be based on it.

In order to avoid clutter in our pull requests, we're going to be closing any pull request that isn't targeting 4.0 on the 31st of July, 2018. Please rebase your pull request before then.

@leezer3 leezer3 changed the base branch from develop to 4.0 July 5, 2018 18:25
@leezer3
Copy link
Contributor Author

leezer3 commented Jul 5, 2018

Rebased & squelched into a single commit.


if (command)
{
OnKeyDown(Key.Command, KeyboardState[Key.AltLeft]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the use of the alt left key here intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's intentional, copying the pattern from those above.

Modifiers on OS-X / Cocoa don't generate a keydown state event per-se, but rather are passed as flags in a window event message (Including ALT).
If I understand the intent of the original code correctly, the virtual LeftAlt key is being used to define that any given modifier was valid at the last keypress event, and the modifiers flags are used to determine which.

Copy link
Contributor

@tyronx tyronx Nov 12, 2018

Choose a reason for hiding this comment

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

That.... doesn't seem to make much sense to me. Why would a modifier not be valid? Also this method seems only called by the cocoanative window and I still cant get CMD+V to work. This seems like a typo to me tbh, and the reason why CMD+V doesnt work. Testing now...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because a modifier isn't a key & generates no events.

We can therefore hold one key and a modifier. Release the modifier while holding the key & press another.
The first is now invalid, but no keypress events have been generated.

If this don't make sense it's because its from the phone....

Copy link
Contributor

@tyronx tyronx Nov 12, 2018

Choose a reason for hiding this comment

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

Oh, but I just realize that this second argument just sets the KeyDownArgs.IsRepeat field to determine if its a key repeat event when holding down the key for a longer time.

The first is now invalid, but no keypress events have been generated.

Keypress events do not consider the modifiers anyway though (at least not OpenTK, the Operating system does). Only the keydown events pass on the modifiers. And opentk registers any cocoa keydown/keyup events so even your case should be handled correctly.

Copy link
Contributor Author

@leezer3 leezer3 left a comment

Choose a reason for hiding this comment

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

It's marginally crappy code, but rehacking the keypress events for the native window isn't something I'm going after on my own.


if (command)
{
OnKeyDown(Key.Command, KeyboardState[Key.AltLeft]);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's intentional, copying the pattern from those above.

Modifiers on OS-X / Cocoa don't generate a keydown state event per-se, but rather are passed as flags in a window event message (Including ALT).
If I understand the intent of the original code correctly, the virtual LeftAlt key is being used to define that any given modifier was valid at the last keypress event, and the modifiers flags are used to determine which.

@Nihlus
Copy link
Contributor

Nihlus commented Jul 6, 2018

Alright, seems fine. I'll merge it, and we can test it as a part of the general 4.0 overview.

@Nihlus Nihlus merged commit 3b5ef48 into opentk:4.0 Jul 6, 2018
@@ -121,6 +121,10 @@ public enum Key
/// </summary>
Menu,

/// <summary>The Command key.</summary>
/// <remarks>Valid on OS-X only</remarks>
Command,
Copy link
Contributor

Choose a reason for hiding this comment

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

Argggh, this took me like 4 hours to figure out.
I tried your patch on my fork. This one enum entry broke all keyboard inputs on mac os for my game because it caused all subsequent enum indices to be shifted by 1 which caused my game internal keycode representation to be incorrectly mapped.
This is not a bug per se but perhaps its a good idea to move this enum entry to the very bottom for backwards compatibility?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Dunno.

I would have thought most people are using the actual enum values, rather than the index directly?
It was deliberately added there so it was grouped with the other OS-X modifiers rather than elsewhere.

You've absolutely proved my point about this biting us though!

Copy link
Contributor

@tyronx tyronx Nov 12, 2018

Choose a reason for hiding this comment

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

I have an abstraction layer to abstract away OpenTK itself so I can switch to another graphics library / toolkit should the need ever arise, hence the mapping

@leezer3 leezer3 deleted the OSX-Modifiers branch November 12, 2018 14:12
@tyronx
Copy link
Contributor

tyronx commented Nov 12, 2018

Hokay, more tests revealed that the keydown event for the command key itself is fired and works.

But when you do a key combination like Command + V the KeyboardKeyEventArgs for that keydown event does not have the Command modifier flag set to on because you forgot to patch KeyboardKeyEventArgs.cs

@tyronx
Copy link
Contributor

tyronx commented Nov 12, 2018

Found even more bugs. Using Command+V also triggers a Keypress event for 'V', which it shouldn't.

Judging by the lack of information on that in the online apple cocoa documentation we have to literally hardcode those special cases.

The windows implementation handles this by listening to a CHAR event so neatly does the work for us when handling hotkeys (as in, not trigger a keypress when such shortkey is used).

@Perksey
Copy link
Contributor

Perksey commented Nov 12, 2018

@tyronx Should report those bugs in a new issue ;)

@tyronx tyronx mentioned this pull request Nov 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants