vsg-dev / VulkanSceneGraph

Vulkan & C++17 based Scene Graph Project
http://www.vulkanscenegraph.org
MIT License
1.32k stars 212 forks source link

KeyPress events not intuitive on Windows #342

Closed sbrkopac closed 3 years ago

sbrkopac commented 3 years ago

Describe the bug When pressing a key on the windows platform, the proper keys are buffered with VSG but the results aren't intuitive. Also opened vsg-dev/vsgExamples#115

To Reproduce Steps to reproduce the behavior:

  1. run vsgintrospection in the vsgExamples repository
  2. hit one of the defined keys to trigger the builder on the mesh

Expected behavior The new geometry should be displayed on the mesh after hitting the correct key

Desktop (please complete the following information):

Additional context When a keystroke happens in windows (I will use the 'b' key for this example) the correct key stroke is picked up:

image

From here the key is converted to an ascii character:

char asciiKey[2];
int numChars = ::ToAscii(static_cast<UINT>(wParam), (lParam>>16)&0xff, keyState, reinterpret_cast<WORD*>(asciiKey), 0);
if (numChars>0) modifiedKeySymbol = (vsg::KeySymbol)asciiKey[0];

This causes the correct symbol to show up in the modifiedKeySymbol variable:

image

So everything works correctly but when the user goes to use the resulting buffered event in a client application - it's just not intuitive:

if (keyPress.keyBase == 'b')
{
    scenegraph->addChild(builder->createBox(info));
}

image

Note the keyBase vs keyModified. I don't have a linux machine but I'm assuming this isn't the case there.

sbrkopac commented 3 years ago

I took a peek at what OpenSceneGraph does and it looks like it works slightly opposite to VSG. You can see here. OSG tracks keyPress (the resulting value of ::ToAscii) and an unmodified key (the resulting key from the key remap).

@robertosfield I think it makes more sense to provide keyBase as the "modified" key to the end-user application.

robertosfield commented 3 years ago

I have just checked Linux, and VulkanSceneGraph/src/vsg/platform/unix.Xcb_Window.cpp is report 'a' and 'a' for keyBase and and keyModified when I don't press shift, and don't have caps lock on. When I press shift or toggle on caps lock then I get 'a' and 'A' for keyBase and keyModified.

From your description Windows is reporting the opposite. I'm afraid I don't have a Windows dev system so haven't ever been able to test it personally. Tom Hogarth, when he did the Windows port, must have gone with the interpretation suggested by the Win32 API which is opposite to what X11/Xcb uses and opposite to what I assumed was normal.

It does look like this should be flipped, for sure all platforms should work the same, and a modified version of a key should be the one relating to the needing a modifier active i.e. shift or caps lock. If you generate a PR for this I'll be happy to merge.

Cheers, Robert.

On Tue, 12 Oct 2021 at 00:14, Sam Brkopac @.***> wrote:

Describe the bug When pressing a key on the windows platform, the proper keys are buffered with VSG but the results aren't intuitive. Also opened vsg-dev/vsgExamples#115 https://github.com/vsg-dev/vsgExamples/issues/115

To Reproduce Steps to reproduce the behavior:

  1. run vsgintrospection in the vsgExamples repository
  2. hit one of the defined keys to trigger the builder on the mesh

Expected behavior The new geometry should be displayed on the mesh after hitting the correct key

Desktop (please complete the following information):

  • OS: Windows 10

Additional context When a keystroke happens in windows (I will use the 'b' key for this example) the correct key stroke is picked up:

[image: image] https://user-images.githubusercontent.com/1939712/136865047-c57207bc-8af3-4243-8fe1-17093cc98816.png

From here the key is converted to an ascii character:

char asciiKey[2]; int numChars = ::ToAscii(static_cast(wParam), (lParam>>16)&0xff, keyState, reinterpret_cast<WORD*>(asciiKey), 0); if (numChars>0) modifiedKeySymbol = (vsg::KeySymbol)asciiKey[0];

This causes the correct symbol to show up in the modifiedKeySymbol variable:

[image: image] https://user-images.githubusercontent.com/1939712/136865140-c3ae8c90-d8dd-46f4-a389-63bada5c99ba.png

So everything works correctly but when the user goes to use the resulting buffered event in a client application - it's just not intuitive:

if (keyPress.keyBase == 'b') { scenegraph->addChild(builder->createBox(info)); }

[image: image] https://user-images.githubusercontent.com/1939712/136865264-07f00215-c842-4be3-b22a-b80d4a1533ca.png

Note the keyBase vs keyModified. I don't have a linux machine but I'm assuming this isn't the case there.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/vsg-dev/VulkanSceneGraph/issues/342, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAKEGUEEQHDLAEOEI7CAAJDUGNVU3ANCNFSM5FZHQRYA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.