Cancel key repeat in GUI

Hello all.

How can I manage a long key press ?

QT repeats keyDown and keyUp actions…

(
FlowView().front
.keyDownAction_{"down".postln}
.keyUpAction_{"up".postln}
)

prints constantly " down up down up down up" meanwhile I never release the key
Is that really the intended behaviour ?
Do I really have to make by myself a Timer or there is a better solution ?

1 Like

https://www.listarc.bham.ac.uk/lists/sc-users-2014/msg38977.html
https://www.listarc.bham.ac.uk/lists/sc-users/msg60200.html
https://www.listarc.bham.ac.uk/lists/sc-users/msg60206.html

Ok, but the problem stays the same

By example, in one solution from your links :

(
w = Window.new.front;
k = Set[];
w.view.keyDownAction_({
arg view, char, mod, uni, key;
if(k.includes(key).not) {
"key down".postln;
k.add(key);
};
});

w.view.keyUpAction_({
arg view, char, mod, uni, key;
"key up".postln;
k.remove(key);
});
)

the remove action is always activated, because i cannot discriminate between a ‘false’ key up, and a real one, so I keep removing the key from the set, and it’s the same problem.

For now, the only solution is to make a Routine, and cancel every down action below 0.03s, and defer in the up action after 0.27s, if the chronometer is not updated, so trigger the up event.
That’s so heavy, and clearly not the good way. One has to see in the QT base code if it is possible to implement the real solution found on another forum

Since you tagged your question with Qt, I assume your are using Qt key events - in that case, use QKeyEvent::isAutoRepeat() to check if the key event is a "real" key event or an autorepeat event.
1 Like

Oh, thank you!
This is really helpful!

best,

prko

I made this workaround based on your idea (for future reference):

w = Window("Process World Keypresses", Rect(0, 0, 1000, 500)).front;

// The routines are a workaround to avoid repeated keypresses
~keyUpRepeatRoutines = Dictionary[];

w.view.keyDownAction = {
	|doc, char, mod, unicode, keycode, key|
	char.postln;
	~processes.do { |proc|
		if(proc.key == char) {
			~keyUpRepeatRoutines[char.asSymbol].stop;
			proc.start();
		};

	};
};

w.view.keyUpAction = {
	|doc, char, mod, unicode, keycode, key|
	~processes.do { |proc|
		if(proc.key == char) {

			// suspend the process only if the routine isn't stopped first (which is the case if the key is repeated)
			~keyUpRepeatRoutines[char.asSymbol] = Routine({
				0.01.wait;
				proc.suspend();
			}).play;
		};

	};
};

proc.start(); checks if the process is active and if so doesn’t restart it thereby saving me from using two different routines.