Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Inhibit more keyboard event during execution of function

1 view
Skip to first unread message

Mathias Dahl

unread,
Dec 28, 2009, 4:49:40 PM12/28/09
to
I have made a small game for my kid that lets him press a key and that
will play a sound and display an image. It is implemented as a major
mode with a keymap where each key is defined using `define-key' and
bound to a special play command with a string of what to play (say,
"cow"). Now, it works for me, but when I tested this on my son today he
kept the key pressed way longer than I do, with the effect that the key
repeats, playing the sound many times. Quite annoying. Is there a way to
get around this? I have been thinking of having some timing built in so
that I will not play again unless a certain time has passed.

Also, even though I tell Emacs to draw the image first (using
`insert-image-file'), it is not displayed until the sound has stopped
playing (I use `play-sound-file'). Any way around this?

Thanks!

/Mathias

Kevin Rodgers

unread,
Dec 29, 2009, 1:51:40 AM12/29/09
to help-gn...@gnu.org

I don't know if this will work, but you could try let-binding
unread-command-events to nil while the sound is being played.
The idea is that any input events would be added to the queue,
but when the sound is done the queued events would be discarded
and the command loop wouldn't see them.

--
Kevin Rodgers
Denver, Colorado, USA

Mathias Dahl

unread,
Dec 29, 2009, 3:03:50 PM12/29/09
to
> I don't know if this will work, but you could try let-binding
> unread-command-events to nil while the sound is being played.
> The idea is that any input events would be added to the queue,
> but when the sound is done the queued events would be discarded
> and the command loop wouldn't see them.

Thanks! It sounded like a good idea but it did not work. This is what
I did:

(defun esb-play (thing)
"Play sound and display image for THING."
(let ((unread-command-events nil))
(esb-display-image (concat esb-data-dir thing ".jpg"))
(play-sound-file ...
...

If I keep a key pressed or type it repeatedly it will still
"record" (queue?)
what is pressed during play.

Any other ideas?

/Mathias

Lennart Borgman

unread,
Dec 29, 2009, 3:53:16 PM12/29/09
to Mathias Dahl, help-gn...@gnu.org
On Tue, Dec 29, 2009 at 9:03 PM, Mathias Dahl <mathia...@gmail.com> wrote:
>
> If I keep a key pressed or type it repeatedly it will still
> "record" (queue?)
> what is pressed during play.
>
> Any other ideas?

Put a keymap in emulation-mode-map-alist with `ignore' as default key
during the play?


Ilya Zakharevich

unread,
Dec 29, 2009, 5:11:58 PM12/29/09
to

If you sound is played syncroneously, just introduce a global
variable, set it on during sound play, and do sound play conditionally
- only if the variable is not set.

If the play is async - may be much harder...

Hope this helps,
Ilya

Mathias Dahl

unread,
Dec 29, 2009, 5:38:27 PM12/29/09
to
> If you sound is played syncroneously, just introduce a global
> variable, set it on during sound play, and do sound play conditionally
> - only if the variable is not set.

The problem is not that the same sound is played at the same time, the
problem is that during the play the system accepts more keyboard
events and adds them to the queue, later playing sound when the key
binding is executed. If I use a global variable it will work in the
sense that no other/new sound will be played during play, but when the
playing is done and I set the global variable to false again the next
keyboard event will fire. Right?

Mathias Dahl

unread,
Dec 29, 2009, 5:40:40 PM12/29/09
to
> Put a keymap in emulation-mode-map-alist with `ignore' as default key
> during the play?

You don't happen to have a recipe for that, do you? :) I tested it
briefly but either I did not do it correctly or the approach does not
work.

Can't I just temporarily rebind the key that played the current
"thing" and rebind it again afterwards in my own keymap?

Mathias Dahl

unread,
Dec 29, 2009, 5:56:16 PM12/29/09
to

I solved the first problem by saving the time when the sound is
playing and then refusing to play a sound again until at least a
second has passed. Feels ugly but seems to work okay.

Any takers on the second problem? Can I force redisplay of the image
in the display buffer before the sound is played?

Mathias Dahl

unread,
Dec 29, 2009, 6:00:32 PM12/29/09
to
> Any takers on the second problem? Can I force redisplay of the image
> in the display buffer before the sound is played?

Hehe, turns out there is a function called `redisplay' and when I put
that between the display of the image and the playing of the sound I
get what I want. Yay!

Lennart Borgman

unread,
Dec 29, 2009, 6:52:31 PM12/29/09
to Mathias Dahl, help-gn...@gnu.org
On Tue, Dec 29, 2009 at 11:40 PM, Mathias Dahl <mathia...@gmail.com> wrote:
>> Put a keymap in emulation-mode-map-alist with `ignore' as default key
>> during the play?
>
> You don't happen to have a recipe for that, do you? :) I tested it
> briefly but either I did not do it correctly or the approach does not
> work.


Look in tabkey2.el


> Can't I just temporarily rebind the key that played the current
> "thing" and rebind it again afterwards in my own keymap?


Yes, of course. The way above is perhaps more general if you want to redo it.


Andreas Politz

unread,
Dec 30, 2009, 4:52:47 AM12/30/09
to help-gn...@gnu.org
Mathias Dahl <mathia...@gmail.com> writes:

There is also a function `discard-input', which might be helpful.

-ap

Mathias Dahl

unread,
Dec 31, 2009, 2:51:52 AM12/31/09
to
> There is also a function `discard-input', which might be helpful.

Aha! First I did not think it helped, I had the call to it before I
play the sound. When I moved it to afterwards it works as I want it
to. I guess it makes sense: *after* playing I want to get rid of any
input events I got in the meantime. Now I can get rid of the ugly
measure-time-hack.

Many thanks, Andreas!

0 new messages