Page 1 of 1

Sending key events slow

Posted: 6. Oct 2013, 14:27
by Thorsten77
Hi,

I'm using IKeyboard.putScancode(int) to send key events (keydown/keyup) in an application, but the method call sometimes is very slow. Often, it takes just like 5ms which is expected, but then there are situations where the call takes half a second. If the keydown event is delayed, this leads to registering multiple keys in the guest OS, similar to holding down a key long enough so repetition starts. I'm not 100% sure what causes the big delays, but fwiw another thread in my application regularly takes a screenshot and I suspect that there is a kind of blocking (when the screenshot is taken, one cannot input a key event directly)?
I'm using Virtualbox 4.2.18 and the same version of the API in Java over XPCOM. The host OS is MacOS and the guest is Windows 7.
Any ideas how I can improve the speed/avoid the blocking?

Re: Sending key events slow

Posted: 8. Oct 2013, 08:16
by noteirak
The inner working of Virtualbox are best answered on the Dev Mailing list, but in any case your piece of code would help here.

Re: Sending key events slow

Posted: 8. Oct 2013, 11:13
by michaln
Send a key down event together with the corresponding key up event. That will minimize the likelihood of delays.

Re: Sending key events slow

Posted: 9. Oct 2013, 02:21
by Thorsten77
Thanks for the answers!
I tried to send all strokes at once and the delay between them is then minimized, however, it seems weird to me that some calls still take a lot of time anyway.

I wrote a little test program, which just presses the x key over and over again (into a notepad window):

Code: Select all

        IConsole console = session.getConsole();
        IKeyboard keyboard = console.getKeyboard();
        long totalTime =0;
 
       for (int i = 0; i < 1000; i++) {
            long start = System.currentTimeMillis();
            keyboard.putScancode(KeyboardSupport.getIntMakeCode(KeyEvent.VK_X));
            keyboard.putScancode(KeyboardSupport.getIntBreakCode(KeyEvent.VK_X));
            long duration = System.currentTimeMillis() - start;
            System.out.println(duration);
            totalTime += duration;
        }
        System.out.println(totalTime);
Of the 1000 loops, 836 had a time of less than 10ms for both method calls. However, then there are always iterations that take a time way longer than that. Here's an excerpt from the output:

Code: Select all

1
2
114
6
3
2
3
60
59
3
2
115
4
4
3
120
4
109
4
4
2
1
1
2
2
169
3
3
2
I also tested the same while taking screenshots: the times get a little bit slower, but not much and the same pattern occurs compared to not doing anything else. So, my initial thought that this might be the issue seems to be wrong.

However, I observed an interesting thing while testing: when I perform the little test program and notepad is running and has the focus (i.e. an application consumes the input) i get the issue that some events are processed really delayed. However, when I run the program without notepad running (so i just send the keys, but there is no application that consumes the event), all iterations worked super fast (<5ms). Then I run a program inside the VM which installs a keyboard event logger and processes it which takes some time, but even then the events I send using the API are all instant.

So I wonder if the cause of the slow events is that if the key results in a change of the graphics inside the VM, it leads to frequently slowing down?

Re: Sending key events slow

Posted: 9. Oct 2013, 06:17
by noteirak
Things take more time into a VM, timming issues are part of virtualization AFAIK, so from my understanding this is normal behaviour. Maybe michalm can confirm/infirm this?

Re: Sending key events slow

Posted: 9. Oct 2013, 11:08
by michaln
noteirak wrote:Things take more time into a VM, timming issues are part of virtualization AFAIK, so from my understanding this is normal behaviour. Maybe michalm can confirm/infirm this?
First of all, this is a cross-process call subject to host scheduling delays etc. The VM itself is subject to scheduling as well and introduces additional overhead. Not surprisingly, the performance highly depends on the host system's speed and load.

Yes, triggering graphics updates in the guest can conceivably slows things down. It means the host system as a whole has more work to do.