Open kicumkicum opened 9 years ago
@kicumkicum, are you using the latest blessed? There was a race condition with binding key listeners on textareas a little while ago, but it was fixed.
I'm also seeing this kind of behavior with Blessed 0.1.7.
If I have two textbox
elements, boxOne
and boxTwo
and define an on('click'...
event that does nothing, i.e.:
boxTwo.on('click', function(data) {
// Nothing
});
If boxOne
was focused for input and I now click onto boxTwo
, boxTwo
does not receive focus and any further typing in boxOne
will be duplicated.
Additional calls to a focus()
method on another element can cause this input to be quadruplicated.
Not quite sure whats going on here but I will be happy to provide more info.
I use blessed 0.1.81 I have two blessed.list and one blessed.textarea I loging remove listener in readInput and add listener in nextTick. task keys:
Any update on this?
I revert this commit https://github.com/chjj/blessed/commit/b42308c7cc3e544821254a0095082d22b60f5af9 and work for my, but i don't know what i'm doing.
I'm still getting this issue, and I think it happened because I have multiple controls listening for the escape key on input, and then refocusing a textbox on this happening. When I removed this callback, it stopped happening.
program.key('escape', function() {
text.focus();
});
blessed 0.1.81
In case anyone else has this issue I created a workaround that does not require a fork. You can use this function to add a working inputFocus
and inputBlur
to a textbox instance. This will cleanup the listeners on blur that cause the duplication.
export function AddBlurToTextBox(textBox, handlers) {
textBox.inputFocus = () => {
textBox.inputBlur()
textBox.addHandlers()
textBox.focus()
}
textBox.addHandlers = () => handlers()
textBox.inputBlur = () => {
textBox.removeListener('keypress', textBox.__listener);
delete textBox.__listener;
textBox.removeListener('blur', textBox.__done);
delete textBox.__done;
textBox.screen.focusPop(textBox)
}
}
Usage: Note you must add all your handlers to the callback so they can be reattached on focus
AddBlurToTextBox(input, () => {
input.on('keypress', (ch, key) => {
//do something
})
})
Clearly not ideal -- but I don't want to own this code by forking it
For me , removing the explicit focus handler for the textbox and setting the option inputOnFocus: true
solves this issue.
I have the same Problem. but i use it only for an intro and i destroy after that the screen. after that i use inquirer for questions and dubble input. @acunniffe i dont now but i cant get working your fix for me.
module.exports = ({screen, box, image, bigtext}, callback) => {
const sc = screen({
smartCSR: true
});
const bx = box({
parent: sc,
height: "100%",
width: "100%",
optimierung: "cpu",
});
sc.append(bx);
let i = 100;
let img = image({
parent: bx,
top: 0,
left: i + "%",
width: "34%",
height: "100%-14",
type: "ansi",
ascii: "density",
file: __dirname + "/../../img/Mond.png",
});
bigtext({
parent: bx,
content: "MoonShop",
top: "100%-14",
style: {
fg: "white",
},
left:"center",
align:"center",
valign:"middle",
});
function AddBlurToTextBox(sc, handlers) {
sc.inputFocus = () => {
sc.inputBlur();
sc.addHandlers();
sc.focus();
};
sc.addHandlers = () => handlers();
sc.inputBlur = () => {
sc.removeListener("keypress", sc.__listener);
delete sc.__listener;
sc.removeListener("blur", sc.__done);
delete sc.__done;
sc.screen.focusPop(sc);
}
}
AddBlurToTextBox(sc, () => {
});
function intro(){
if(i > 33){
i--;
img.left = i + "%";
sc.render();
setTimeout(intro,50);
} else {
setTimeout(() => {
sc.destroy();
console.clear();
callback();
}, 4000);
}
}
intro();
};
For Whatever it's worth, I spent quite a while battling this problem and finally came up with a working solution based on @acunniffe's code. My slightly modified version is below.
function AddBlurToTextBox(textBox, handlers) {
textBox.inputFocus = () => {
textBox.inputBlur()
textBox.addHandlers()
textBox.focus()
}
textBox.addHandlers = () => handlers()
textBox.inputBlur = () => {
setImmediate(() => {
textBox.removeListener('keypress', textBox.__listener);
delete textBox.__listener;
textBox.removeListener('blur', textBox.__done);
delete textBox.__done;
});
}
}
In my code, I just call the inputBlur() in my submit handler. - when the input is focused again it behaves normally.
The issue seems to be that TextArea is adding it's listeners in a nextTick()
(which is really setImmediate()) - which means just removing them doesn't work because they don't exist yet. Putting the removal in a setImmediate makes the removal happen after they are actually added. No more key duplication. :)
I see this behavior in my app vknplayer, after update blessed from 0.0.47 to 0.0.48 What could be the reason?