I am recently learning electron I have encountered a problem that I want to listen ESC in both process,
In Main process,
menu.append(new MenuItem({
label: "Hide on Escape",
visible: false,
accelerator: "Escape",
click: (item, window, event) => {
if (window.isVisible()) {
window.hide();
}
}
}))
In Render Process,
// on Key press Handler
const onKeyDownHandler = (event: React.KeyboardEvent) => {
if (isContentEditable && event.key === "Enter") {
applyContentEditable();
} else if (event.key === "Enter") {
onSelected && onSelected(pair);
} else if (event.key === "Delete") {
onDelete && onDelete(pair);
} else if (event.key === "F2") {
setIsContentEditable(true);
} else if (event.key === "Escape") {
resetContentEditable(); // Stop Renaming and get back to default
}
}
But this didn't work the window hides before the render process. How can I Stop hide when it is listened by Render Process
There is an event.stopPropagation() method which prevents further propagation/calls on the same event Docs
And there is event.preventDefault() which can be used to stop default handling Docs
I still don't quite fully understand your setup and what you are try to achieve.
Another solution is to stop listening on the escape key in the main process at all. Only listen in the render process and then pass the event manually to the main process in case you want to take some action there as well (or the other way around, depending on what makes more sense for you).
For this passing you are probably looking at the electron ipcMain module https://www.electronjs.org/docs/latest/api/ipc-main
In my componentDidMount I am trying to remove a localstorage item and also adding an event listener for further changes in the localstorage and it is not working
componentDidMount() {
localStorage.removeItem("receivedLocation");
window.addEventListener("storage", event => {
console.log("Event listener triggered");
if (event.key === "receivedLocation" && event.newValue === true) {
this.setState({
receivedLocation: true
});
}
});
}
Whereas if I remove the update item it works fine.
componentDidMount() {
window.addEventListener("storage", event => {
console.log("Event listener triggered");
if (event.key === "receivedLocation" && event.newValue === true) {
this.setState({
receivedLocation: true
});
}
});
}
I am unable to reset the localstorage and also listen to future changes in the localstorage
The storage events do not fire in the current document. It is used to notify the other open tabs of your app of some change.
The storage event of the Window interface fires when a storage area
(localStorage or sessionStorage) has been modified in the context of
another document
If you are trying to notify other components in the current tab, you can use the DOMEvents for that.
const event = new Event('EVENT_NAME', { detail: { yourPayload }});
window.dispatchEvent(event);
// in your component
window.addEventListener('EVENT_NAME', configChangedHandler, false);
// cleanup
window.removeEventListener('EVENT_NAME', configChangedHandler);
I want to call a SOS function when user long press the power button.
If there is no library to do this, is there any native method to do so?
You can use this library to run a code when the home button is pressed
react-native-home-pressed
You can change the keycode creating a fork of the repository
and, check the long press with a timer.
UPDATE:
You can use this library to get a keycode event of key up and key down event.
Example:
componentDidMount() {
KeyEvent.onKeyDownListener((keyEvent) => {
if (keyEvent.keyCode === 'Keycode of the power button'){
this.timeout = setTimeout(() => {
//Your SOS Function here
}, 1000)
}
});
KeyEvent.onKeyUpListener((keyEvent) => {
if (keyEvent.keyCode === 'Keycode of the power button'){
clearTimeout(this.timeout)
}
})
}
componentWillUnmount() {
KeyEvent.removeKeyDownListener();
KeyEvent.removeKeyUpListener();
}
How can I detect if the shift key is currently pressed down? I have a text input, and when the user presses the enter key I only want to submit the form if they are not currently pressing the enter key (same form functionality as Facebook Messenger on desktop).
Here is my text input:
<TextInput
style={styles.input}
placeholder={'Enter message'}
onKeyPress={this.handleKeyPress}
/>
And here is the handler:
handleMessageInputKeyPress(e) {
if(e.nativeEvent.key == "Enter"){
// Now check if the SHIFT key is currently pressed or not...
}
}
You can use event listeners to detect any time a key is pressed (or unpressed), then filter the results for the key you want to use as a conditional. Here's an example using hooks:
const [shiftHeld, setShiftHeld] = useState(false);
function downHandler({key}) {
if (key === 'Shift') {
setShiftHeld(true);
}
}
function upHandler({key}) {
if (key === 'Shift') {
setShiftHeld(false);
}
}
useEffect(() => {
window.addEventListener('keydown', downHandler);
window.addEventListener('keyup', upHandler);
return () => {
window.removeEventListener('keydown', downHandler);
window.removeEventListener('keyup', upHandler);
};
}, []);
This will change the state to true of false depending on whether the shift key is held down or not. Then you can plug that value in anywhere you need it.
Tip: You can use this format to listen for any other key. I had a hard time finding documentation on what the keys are called. If you have trouble finding the key name, implement this code then console log key just before the if statement in the downHandler.
Also, make sure you leave the listeners in a useEffect, otherwise you'll get data leaks.
For those who are still looking for the solution:
It seems the event received by the callback onKeyPress has the following properties:
It's nice to see it also has ctrlKey & altKey.
So the solution would be:
<TextInput
onKeyPress={event => {
if (event.shiftKey && event.key === "Enter"){
// ...
}
}} />
On Mac browsers, javascript does not receive keyup events for most keys (other modifier keys seem to be an exception) when the metakey is down. Use this jsfiddle to demonstrate (focus the result area and try something like cmd + x, the x will not receive a keyup event):
http://jsfiddle.net/mUEaV/
I've reproduced this in stable releases for Chrome, FF, Safari and Opera. The same thing does not seem to happen with the control key in Windows 7.
Is the OS hijacking the keyup event? This seems especially strange since commands that use the metakey such as save, find, cut, copy, etcetera all activate on keydown not on keyup, and can be hijacked by the javascript just fine.
It's simply not possible to get the onKeyUp events when meta is used, I learned today. Very unfortunate and difficult to work around. You'll have to emulate them some other way.
Edit: To clarify, this is only on Mac and occurs due to OS level handling of the event. It cannot be overridden. Sorry to be the bearer of bad news.
Although event.metaKey returns false, event.keyCode and event.key are still populated.
document.addEventListener('keyup', function(e) {
console.log(e.metaKey || e.key);
});
Click here then press the Command, Control, or Option keys.
Is the browser window retaining the focus when you press those keys? In windows you can get similar result when pressing windows+R or CTRL+ESC and similar key combinations that make browser to loose focus and that results in missed events.
While keyup events are indeed not available when the meta key is pressed, you can still get keydown events for all keys, as well as keyup events for the meta key itself.
This allows us to just simply keep track of the state of the meta key ourselves, like so:
let metaKeyDown = false;
window.addEventListener("keydown", event => {
if (event.key == 'Meta') { metaKeyDown = true; }
});
window.addEventListener("keyup", event => {
if (event.key == 'Meta') { metaKeyDown = false; }
});
By now additionally checking for the main key, plus cancelling the default behavior with Event.preventDefault() we can easily listen for key combinations (like here e.g. CMD+K) and prevent the browser from handling them:
let metaKeyDown = false;
window.addEventListener("keydown", event => {
if (event.key == 'Meta') { metaKeyDown = true; }
if (event.key == 'k' && metaKeyDown) {
event.preventDefault();
console.log('CMD+K pressed!');
}
});
window.addEventListener("keyup", event => {
if (event.key == 'Meta') { metaKeyDown = false; }
});
(Note the observation of the k key taking place already on keydown.)
Also, please be aware that when used incorrectly, this can break standard browser functionality (e.g. like CMD+C or CMD+R), and lead to poor user experience.
You can create an artificial keyup event by waiting for a certain period after the last keydown event. The only caveat is people will have different repeat rates on their os.
https://jsfiddle.net/u7t43coz/10/
const metaKeyCodes = ["MetaLeft", "MetaRight"];
const shiftKeyCodes = ["ShiftLeft", "ShiftRight"];
const ctrlKeyCodes = ["ControlLeft", "ControlRight"];
const altKeyCodes = ["AltLeft", "AltRight"];
const modifierKeyCodes = [
...metaKeyCodes,
...shiftKeyCodes,
...ctrlKeyCodes,
...altKeyCodes
];
// record which keys are down
const downKeys = new Set()
const artificialKeyUpTimes = {}
function onKeydown(e) {
downKeys.add(e.code);
// do other keydown stuff here
console.log("meta", e.metaKey, e.code, "down")
// check if metaKey is down
if (metaKeyCodes.some(k => downKeys.has(k))) {
downKeys.forEach(dk => {
// we want to exclude modifier keys has they dont repeat
if (!modifierKeyCodes.includes(dk)) {
// fire artificial keyup on timeout
if (!artificialKeyUpTimes[dk])
setTimeout(
() => fireArtificialKeyUp(dk, e),
500
);
artificialKeyUpTimes[dk] = Date.now();
}
});
}
}
function fireArtificialKeyUp(code, e) {
// if enough time has passed fire keyup
if (Date.now() - artificialKeyUpTimes[code] > 100) {
delete artificialKeyUpTimes[code];
//if key is still down, fire keyup
if (downKeys.has(code)) {
const eCode = isNaN(code) ? { code: code } : { keyCode: code };
document.dispatchEvent(
new KeyboardEvent("keyup", { ...e, ...eCode })
);
}
} else {
setTimeout(() => fireArtificialKeyUp(code, e), 100);
}
}
function onKeyup(e) {
downKeys.delete(e.code);
// do keyup stuff here
console.log("meta", e.metaKey, e.code, "up")
}
document.addEventListener("keydown", onKeydown)
document.addEventListener("keyup", onKeyup)