#Keypress while Dialog open
1 messages · Page 1 of 1 (latest)
Sure
thanks for taking the time to debug this
I may be getting confused about which event firing from the debugger is which, but I believe those are correct
Am I helping?
you're helping
I'ma write up a bug and push this fix right away
our next release is later this week, but if you want, you could modify the core files to apply the fix or hotpatch that method
Okay, cool. If it helps at all, once this state is entered my boolean never gets set to 'false' no matter how many times I press the shift key.
yeah, because it would fail to match the action on up
do you know how to modify the core files?
I know how to find foundry.js
replace getKeyboardEventContext with
static getKeyboardEventContext(event, up = false) {
const modifierKeycodes = [
"Unidentified",
"AltLeft",
"AltRight",
"ControlLeft",
"ControlRight",
"MetaLeft",
"MetaRight",
"OSLeft",
"OSRight",
"ShiftLeft",
"ShiftRight",
"Space"
];
let pressed = event.key;
// Map certain keys to their codes instead
if ( modifierKeycodes.includes(event.code) || event.code.startsWith("Numpad") ) {
pressed = event.code;
}
pressed = KeyboardManager.standardizeKey(pressed);
/** @type KeyboardEventContext */
let context = {
key: pressed,
action: "",
event: event,
isShift: event.shiftKey || (pressed === "SHIFT"),
isControl: event.ctrlKey || event.metaKey || (pressed === "CONTROL"),
isAlt: event.altKey || (pressed === "ALT"),
hasModifier: false,
modifiers: [],
up: up,
repeat: event.repeat
};
context.hasModifier = context.isShift || context.isControl || context.isAlt;
if ( context.isShift ) context.modifiers.push("SHIFT");
if ( context.isControl ) context.modifiers.push("CONTROL");
if ( context.isAlt ) context.modifiers.push("ALT");
return context;
}
Okay, I may have to wait until I've finished the game I'm running right now to implement that. 😛
What changed there? I have pasted it in and it doesn't seem to have cured the bug, but I'm not sure I successfully saved over foundry.js while it was running.
I have this for it in sources:
static getKeyboardEventContext(event, up = false) {
const modifierKeycodes = [
"Unidentified",
"AltLeft",
"AltRight",
"ControlLeft",
"ControlRight",
"MetaLeft",
"MetaRight",
"OSLeft",
"OSRight",
"ShiftLeft",
"ShiftRight",
"Space"
];
let pressed = event.key;
// Map certain keys to their codes instead
if ( modifierKeycodes.includes(event.code) || event.code.startsWith("Numpad") ) {
pressed = event.code;
}
pressed = KeyboardManager.standardizeKey(pressed);
/** @type KeyboardEventContext */
let context = {
key: pressed,
action: "",
event: event,
isShift: event.shiftKey || (pressed === "SHIFT"),
isControl: event.ctrlKey || event.metaKey || (pressed === "CONTROL"),
isAlt: event.altKey || (pressed === "ALT"),
hasModifier: false,
modifiers: [],
up: up,
repeat: event.repeat
};
context.hasModifier = context.isShift || context.isControl || context.isAlt;
if ( context.isShift ) context.modifiers.push("SHIFT");
if ( context.isControl ) context.modifiers.push("CONTROL");
if ( context.isAlt ) context.modifiers.push("ALT");
return context;
}```
Actually, ignore that, it seems to be somewhat fixed now; it's still not releasing it on initially using that dialog, but subsequent shift-ups are now being detected.
I'm going to manually set the boolean as off when I've done my thing to avoid it getting stuck on, anyway, but it does seem there's an issue in my particular circumstance with the onUp not being fired after my dialog is produced.
Okay, hmm, I notice that after my dialog renders and I do my thing, the button isn't deselecting either, which implies the button event isn't completing fully. I think that's the problem I still have.
That is, if I exit out of the dialog without selecting anything.
@fleet crest I don't know if this is a bug or what, but if a button is left selected after its click event is fired (i.e. because the dialog wasn't re-rendered) it doesn't seem to trigger a keydown event if shift is pressed while the button is still focused.
Ummm?
Yeah, it's a bit hard to show you this, but if a button is focused, no keydown events are fired.
is there a minimum set of code you can share that I can reproduce this with?
I'll see what I can do shortly, but as far as I can tell if a click event is fired on a button and it remains focused after the event, this disables key events until you de focus the button. I'll be home from work in about an hour and will see if I can get a proof of concept working.
@nova ginkgo corroborated the same issue on the League discord.
thanks! that'd be appreciated
@fleet crest Here you go. This macro - just click the demo button and while it's still focused see what happens while you press shift or any other button in the keybinding log. No activity whatsoever.
let content = `<h2>This is a demo button</h2><button type="button">DEMO</button>`;
let width = 400;
let height = 180;
new Dialog({
title: `Roll a track`,
content: content,
buttons: {
ok: {
label: game.i18n.localize("fate-core-official.OK"),
callback: async ()=> {
// Do the stuff here
console.log("You pressed the OK button");
}
}
}
},
{
width:width,
height:height,
}).render(true);```
As soon as you deselect the button, even if the dialog is open, events start firing again.
(I repurposed another macro, apologies for the bits that don't apply)
@strong heron thanks for this, I was able to replicate. The Dialog button being pressed counts as having Focus, so we discarded the keyevent. Although you probably shouldn't have a button that does nothing, it's something we can fix, and so will do so in the next release
Hah, yes, well, I'm not saying it's a desirable effect in the first place, buuut...
In my case the button DOES do something, but I wasn't calling blur on the button afterwards. So if the user closed the dialog rather than pressing the buttons in it to do stuff, the button was staying focused as the application never re-rendered.
So I think there are legitimate situations where it could occur despite it not actually being a button that does nothing. 🙂
I'm just gonna bore you with the specific use case now...
This plus button pops up a dialog to select one or more aspects with free invokes to use to bolster the roll, if you press it with shift held. If they select one or more and hit 'okay' my system adds the bonus to the existing roll and re-renders the app, causing the button to be re-rendered and thus defocused.
If they closed the dialog out without selecting an aspect, the dialog exited without having done anything and the button retained focus. Then, if they clicked on it again with shift held down, once or repeatedly, it maintained the unexpected no-shift-held behaviour.
I've now added a blur event after the function is called so it gets defocused whatever happens, but it's an extra step and not one that's intuitive you'd need to add.
do you have submitOnClose: true on that dialog?
I don't believe so, because it's not actually submitting anything via the standard Foundry workflow.
It does resolve() on close though.
let invokedAspects = await new Promise(resolve => {
new Dialog({
title: game.i18n.localize("fate-core-official.selectAspects"),
content: content,
buttons: {
ok: {
label: "OK",
callback: () => {
resolve($('.free_i_selector'))
}
}
},
default:"ok",
close: () => resolve()
}).render(true);
});```
@fleet crest SHOULD I have submitOnClose as true? 😛
uhh.. man, I don't know haha
I was assuming not since I don't need to capture information such as would be the case with a submission workflow. I just grab the field's value with jquery.
why do you go that route instead of the submission workflow?