buffered key events

I have an app which displays a graph that the user can scroll through using
a scrollbar or the arrow keys. When the system is slow ( especially over
Phindows ) repeated key presses get buffered and the system continues to
scroll once the key has been released.
Is there anyway of telling if there is a que of key events pending ?

Hi Lindsay,

I have spoken to the developer and as far as he knows there is no timestamp in input events. Inside your key handling function you could check to see if there are any more key events pending…(Ph_EV_KEY). The event data is stored in PhKeyEvent_t structure. Inside this structure there is a unsigned long key_flags that you need to check for Pk_KF_Key_Repeat( found in this header file /usr/include/photon/PkKeyDef.h).

I hope this helps
Regards
Brenda


Previously, Lindsey Joyce wrote in qdn.public.qnx4.photon:

I have an app which displays a graph that the user can scroll through using
a scrollbar or the arrow keys. When the system is slow ( especially over
Phindows ) repeated key presses get buffered and the system continues to
scroll once the key has been released.
Is there anyway of telling if there is a que of key events pending ?

Hi Lindsay,

The technique I’ve used is to just increment a global counter in your kestroke handling loops. Don’t do anything else. This makes for quick handling of the keystrokes and none get buffered.

Then I create a timer widget that is called every 200 ms or so, and the timer function checks to see if that counter is above 0. If it is, it performs the desired action based on the keystroke and sets the counter to 0. You’ll probably need to adujust the 200ms to a value that gives you good enough response but without hogging cpu.

-Tom

Previously, Brenda Merpaw wrote in qdn.public.qnx4.photon:

Hi Lindsay,

I have spoken to the developer and as far as he knows there is no timestamp in input events. Inside your key handling function you could check to see if there are any more key events pending…(Ph_EV_KEY). The event data is stored in PhKeyEvent_t structure. Inside this structure there is a unsigned long key_flags that you need to check for Pk_KF_Key_Repeat( found in this header file /usr/include/photon/PkKeyDef.h).

I hope this helps
Regards
Brenda


Previously, Lindsey Joyce wrote in qdn.public.qnx4.photon:
I have an app which displays a graph that the user can scroll through using
a scrollbar or the arrow keys. When the system is slow ( especially over
Phindows ) repeated key presses get buffered and the system continues to
scroll once the key has been released.
Is there anyway of telling if there is a que of key events pending ?

\

Tom Wilson <twilson@atmos.washington.edu> wrote:

The technique I’ve used is to just increment a global counter in your kestroke handling loops. Don’t do anything else. This makes for quick handling of the keystrokes and none get buffered.

That’s a good idea.

Then I create a timer widget that is called every 200 ms or so, and the timer function checks to see if that counter is above 0. If it is, it performs the desired action based on the keystroke and sets the counter to 0. You’ll probably need to adujust the 200ms to a value that gives you good enough response but without hogging cpu.

Or, instead of using a timer, attach a workproc when the counter goes
from 0 to 1. The workproc will run as soon as you empty your event
queue.


Wojtek Lerch (wojtek@qnx.com) QNX Software Systems Ltd.

Wojtek,

You know, I tried the workproc function first, and it had some problems. If I tried to do a lot of graphical window updating while my WorkProc was attached, it would be VERY VERY slow, but if I waited until after my work proc function was removed, it drew at a very fast speed.

For an example, I attach a work proc function to read from a data file (~100MB) to gather timed data that I wanted to graph. I didn’t want the user interface to be frozen during this time, so I used a WorkProc function. I then start reading in data, and on the final iteration of my WorkProc function (no more data in file), I would draw all the data I read in. This would be VERY slow IF I did this data drawing in the final iteration of my WorkProc.

So, I decided to just trip a flag on the last iteration of my WorkProc function and then remove it (return a Pt_END), and do my data drawing in a timer function that checks for that flag being tripped. The drawing was EXTREMELY fast.

Any idea why this would be happening?

Tom


Previously, Wojtek Lerch wrote in qdn.public.qnx4.photon:

Tom Wilson <> twilson@atmos.washington.edu> > wrote:
The technique I’ve used is to just increment a global counter in your kestroke handling loops. Don’t do anything else. This makes for quick handling of the keystrokes and none get buffered.

That’s a good idea.

Then I create a timer widget that is called every 200 ms or so, and the timer function checks to see if that counter is above 0. If it is, it performs the desired action based on the keystroke and sets the counter to 0. You’ll probably need to adujust the 200ms to a value that gives you good enough response but without hogging cpu.

Or, instead of using a timer, attach a workproc when the counter goes
from 0 to 1. The workproc will run as soon as you empty your event
queue.


Wojtek Lerch (> wojtek@qnx.com> ) QNX Software Systems Ltd.

Tom Wilson <twilson@atmos.washington.edu> wrote:

You know, I tried the workproc function first, and it had some problems. If I tried to do a lot of graphical window updating while my WorkProc was attached, it would be VERY VERY slow, but if I waited until after my work proc function was removed, it drew at a very fast speed.

For an example, I attach a work proc function to read from a data file (~100MB) to gather timed data that I wanted to graph. I didn’t want the user interface to be frozen during this time, so I used a WorkProc function. I then start reading in data, and on the final iteration of my WorkProc function (no more data in file), I would draw all the data I read in. This would be VERY slow IF I did this data drawing in the final iteration of my WorkProc.

So, I decided to just trip a flag on the last iteration of my WorkProc function and then remove it (return a Pt_END), and do my data drawing in a timer function that checks for that flag being tripped. The drawing was EXTREMELY fast.

Any idea why this would be happening?

My guess would be that when you do the drawing in a workproc, each
PtSetResource() call ends up drawing in its own draw cycle. This
involves setting up a context, figuring out which widgets need to be
drawn, invoking their draw functions to produce draw commands, and
sending the draw commands to the driver. If you’re setting resources of
the same widget more than once, you may end up redrawing that widget
several times. Even if not, there’s a chance that some widgets will
draw more than once – for instance, the parent of several widgets that
have transparent fill colour.

The solution is to call PtHold() before you do your drawing, and
PtRelease() after. This tells the widget library that instead of
redrawing immediately, your calls to PtSetResources() should just update
the “damage list” of the affected widgets. The actual drawing will be
done from inside PtRelease(), after it’s known which widgets need to be
redrawn and what their final settings are. This way, you not only avoid
redrawing the same widgets multiple times, but you also have all your
widgets draw in one big draw cycle, sending draw commands to the driver
in few big messages rather than many small ones.

The reason your drawing is faster when done in a callback is because
callbacks generally call PtHold() and PtRelease() for you, while
workprocs do not. In general, it’s a good habit to put calls to
PtHold() and PtRelease() around code that sets resources of many widgets
– even if you do it unnecessarily because your code is called by a
callback, it’s harmless.


Wojtek Lerch (wojtek@qnx.com) QNX Software Systems Ltd.