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

onKey events not firing in 0.63.37 #823

Closed
k1mmm opened this issue Aug 28, 2021 · 16 comments
Closed

onKey events not firing in 0.63.37 #823

k1mmm opened this issue Aug 28, 2021 · 16 comments
Assignees

Comments

@k1mmm
Copy link

k1mmm commented Aug 28, 2021

Environment

  1. react-native -v: 0.63.4
  2. npm ls react-native-macos: 0.63.37
  3. node -v: 15.14.0
  4. npm -v: 7.7.8
  5. yarn --version: -
  6. xcodebuild -version: 12.2

Issue

onKey (onKeyUp, onKeyDown etc) events on do not fire.

Steps to Reproduce

  1. Set up using docs
  2. Follow implementation in examples/KeyboardEventExample
<View
  focusable={true}
  enableFocusRing={true}
  onKeyDown={e => console.log(e)}
  onKeyUp={e => console.log(e)}
>
  <Button 
      title={'Test button'}
      onKeyDown={e => console.log(e)}
      onKeyUp={e => console.log(e)}
  />
</View>

Expected Behavior

onKey events to fire

Actual Behavior

No events fired

@HeyImChris
Copy link

You only get the key events you explicitly set as valid. From your example can you add the delimiter of what keys you want to listen to? Something like this works for me in the test app and allows the RCTView to listen to key events for {a, {tab}, {escape}, {enter}, {left arrow}}

validKeysDown={['a', 'Tab', 'Esc', 'Enter', 'ArrowLeft']}

@BafS
Copy link

BafS commented Jan 1, 2022

I tried with validKeysDown (and focusable/enableFocusRing true) but it doesn't work for me either.

Same issue here: #930

@Saadnajmi
Copy link
Collaborator

Saadnajmi commented Jan 1, 2022

I tried with validKeysDown (and focusable/enableFocusRing true) but it doesn't work for me either.

Same issue here: #930

Did you try it on a <View> or a <Button>? I suspect the bug is it doesn't work on the latter.

@BafS
Copy link

BafS commented Jan 1, 2022

Did you try it on a <View> or a <Button>? I suspect the bug is it doesn't work on the latter.

I actually tried on View, Button and TouchableOpacity but none of them handled the key event.

@HeyImChris
Copy link

Did you try it on a <View> or a <Button>? I suspect the bug is it doesn't work on the latter.

I actually tried on View, Button and TouchableOpacity but none of them handled the key event.

@BafS I'm seeing this work correctly for me in the RNTester so trying to figure out what's different on your setup. Did you try the example in RNTester? If so and it's still not working for you, can you post your sample project code so I can repro it and look at what's happening?

@RekiDunois
Copy link

same issue here

I follow the way that adds validKeysDown to <View> in RN-Tester, still not firing.

Environment

react-native -v: 0.64.1
npm ls react-native-macos: 0.64.22
node -v: 16.13.0
npm -v: 8.3.0
yarn --version: 1.22.17
xcodebuild -version: 13.2.1

@ospfranco
Copy link

After playing around it seems a View is not gaining focus even with the focusable prop added to it, maybe this is the reason keyboard shortcuts are not working?

@Saadnajmi
Copy link
Collaborator

Saadnajmi commented Jan 17, 2022

After playing around it seems a View is not gaining focus even with the focusable prop added to it, maybe this is the reason keyboard shortcuts are not working?

Try following the steps under Keyboard Focus at aka.ms/apple-ux-guide . macOS needs an extra OS level setting for views to properly get focus that isn't enabled by default. On Monterrey, there's a second new OS setting (🤷) under accessibility called "Full Keyboard Access" that I haven't documented yet but also improves keyboard focus with react native macOS.

KeyboardFocusUserSetting.png

@RekiDunois
Copy link

After playing around it seems a View is not gaining focus even with the focusable prop added to it, maybe this is the reason keyboard shortcuts are not working?

Try following the steps under Keyboard Focus at aka.ms/apple-ux-guide . macOS needs an extra OS level setting for views to properly get focus that isn't enabled by default. On Monterrey, there's a second new OS setting (🤷) under accessibility called "Full Keyboard Access" that I haven't documented yet but also improves keyboard focus with react native macOS.

KeyboardFocusUserSetting.png

@Saadnajmi I don't think its necessary, because other native apps can use keyboard Focus and receive keyboard events without extra settings either Use keyboard navigation to move focus between controls or Full Keyboard Access

@Saadnajmi
Copy link
Collaborator

After playing around it seems a View is not gaining focus even with the focusable prop added to it, maybe this is the reason keyboard shortcuts are not working?

Try following the steps under Keyboard Focus at aka.ms/apple-ux-guide . macOS needs an extra OS level setting for views to properly get focus that isn't enabled by default. On Monterrey, there's a second new OS setting (🤷) under accessibility called "Full Keyboard Access" that I haven't documented yet but also improves keyboard focus with react native macOS.

KeyboardFocusUserSetting.png

@Saadnajmi I don't think its necessary, because other native apps can use keyboard Focus and receive keyboard events without extra settings either Use keyboard navigation to move focus between controls or Full Keyboard Access

Well that is true... I think React Native macOS specifically checks for this setting and I want to confirm that is indeed where the bug is coming from.

@ospfranco
Copy link

Screen Shot 2022-01-18 at 04 29 46

That sorta seems to be working but now that I think about this, this is not at all what I want, I don't want to have to focus the view in order to receive keyboard events... I want a global keyDown listener

I'm trying to make this work, but no event is being captured: https://stackoverflow.com/questions/32446978/swift-capture-keydown-from-nsviewcontroller any tips?

Also, even though I enabled the settings and the focus ring was there, it seems I could not tab outside the parent component of the currently focused view, so even with the setting enabled, it is still not working properly

@ospfranco
Copy link

ospfranco commented Jan 18, 2022

ok, I figured it out, for those of you out there who actually want to add keyboard shortcuts/events to your app, on applicationDidFinishLaunching (on the main AppDelegate class) you can add the following initialize a global keyDown listener:

NSEvent.addLocalMonitorForEvents(matching: .keyDown) {
  self.keyDown(with: $0)
  return $0
}

an example handler inside the same AppDelegate class:

func keyDown(with event: NSEvent) {
  print("MARKER pressed \(event.characters ?? "NO_CHAR")")
}

Then it is only a matter of sending the event keyCode to the javascript context, I'm still not sure if there is any way to prevent bubbling up (e.g. if a TextInput is focused), but this is better than nothing

@Saadnajmi
Copy link
Collaborator

ok, I figured it out, for those of you out there who actually want to add keyboard shortcuts/events to your app, on applicationDidFinishLaunching (on the main AppDelegate class) you can add the following initialize a global keyDown listener:

NSEvent.addLocalMonitorForEvents(matching: .keyDown) {
  self.keyDown(with: $0)
  return $0
}

an example handler inside the same AppDelegate class:

func keyDown(with event: NSEvent) {
  print("MARKER pressed \(event.characters ?? "NO_CHAR")")
}

Then it is only a matter of sending the event keyCode to the javascript context, I'm still not sure if there is any way to prevent bubbling up (e.g. if a TextInput is focused), but this is better than nothing

What are you trying to prevent from bubbling? If it's a JS event, you could call e.stopPropogation() but I suspect you're talking about something else.

Sounds like the setting I mentioned was the culprit, so I'll close this bug.

@ospfranco
Copy link

ospfranco commented Jan 18, 2022

I wouldn't close this issue, this doesn't solve the actual problem: how do you add global keyboard shortcuts to a react-native-macos app?

on web you would do:

window.addEventListener("keyDown", handler, options)

there you can do e.stopPropagation, but on rn-macos there is no way to do this! these pseudo keyboard events are kinda what's needed, but they don't work! I don't want to have to focus on a view to start receiving its keyboard events. It's impossible to do desktop software without keyboard shortcuts.

@Saadnajmi
Copy link
Collaborator

I wouldn't close this issue, this doesn't solve the actual problem: how do you add global keyboard shortcuts to a react-native-macos app?

on web you would do:

window.addEventListener("keyDown", handler, options)

there you can do e.stopPropagation, but on rn-macos there is no way to do this! these pseudo keyboard events are kinda what's needed, but they don't work! I don't want to have to focus on a view to start receiving its keyboard events. It's impossible to do desktop software without keyboard shortcuts.

The original bug was about just onKey events, not a global keyboard handler. For that, I would open a separate bug. I have a few thoughts on it, but I'd like to keep discussion focused per topic.

@Saadnajmi
Copy link
Collaborator

Re: this thread. I think it's pretty annoying that we need that system preference for keyboard events, so I filed #1007 to track removing the need for that preference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants