device_query icon indicating copy to clipboard operation
device_query copied to clipboard

High CPU usage

Open Leksat opened this issue 2 years ago • 6 comments

(Sorry, I'm completely new to desktop programming. Maybe it's not an issue.)

I ran the code from examples/event_based_print_keys.rs and found that the app uses 300% CPU (on Mac). As I guess, 100% is taken by loop {}, but is it normal that it uses 200% more?

Leksat avatar Aug 25 '22 21:08 Leksat

Ah, it was already discussed in https://github.com/ostrosco/device_query/issues/59

Leksat avatar Aug 25 '22 21:08 Leksat

@ostrosco maybe you could help with an advice?

I'm trying to build a Tauri app which will perform some action based on the clipboard contents. As it will be the most used app feature, I'd like to use a global shortcut. And ideally, this should be "the second copy" command. Basically:

  • I select a text
  • I hit cmd+c => the text is copied to clipboard
  • I hit cmd+c again (in less than 500ms) => the app reads the clipboard and performs the action

Your library would be the perfect solution if not the CPU issue 😬

Do you maybe know in which direction I should look? For me it would be fine if it's working on MacOS only.

Leksat avatar Aug 25 '22 21:08 Leksat

Sure I can give some advice.

One thing to keep in mind is that, if you're using the event-based option, the polling runs in its own thread so it shouldn't impact the main thread for a single process. My recommendation is that if the polling in the event-based option is too frequent for you that you roll your own and select a timeout that you can live with. Something like:

use std::thread;    
use std::time::Duration;    
use device_query::{DeviceQuery, DeviceState, Keycode};    
    
fn main() {    
    thread::spawn(move || {    
        let device_state = DeviceState::new();    
        loop {    
            let keys: Vec<Keycode> = device_state.get_keys();    
            if keys.contains(&Keycode::LControl) && keys.contains(&Keycode::C) {    
                // do your handling in here    
            }    
            // pick whatever timeout works for you in here    
            thread::sleep(Duration::from_millis(1));    
        }    
    });        
}      

Adding a sleep of one millisecond in my print_keys.rs example drops the CPU usage to around 2%.

Since this has come up multiple times, I think I'll look into adding some sort of delay control into the event-based options since realistically no one needs to spin that quick.

ostrosco avatar Aug 26 '22 13:08 ostrosco

Hi I also had the high CPU usage issue. Your code above reduces the CPU usage but then I can't detect key release events. If I hold down the key then whatever code that's triggered by the key runs repeatedly. With the 1 millisecond delay I can still pretty easily accidentally trigger the keyboard shortcut I implemented multiple times even if I meant to just press it once. Of course I could fiddle with the delay but that doesn't seem like the right way.

Any advice for detecting key release events without high CPU usage?

cppxor2arr avatar Sep 24 '22 16:09 cppxor2arr

@cppxor2arr as far as I get it, device_query is really for on-demand querying the keyboard/mouse state. I needed an event-based solution, so I switched to rdev (which has other issues, but it worked for me)

Leksat avatar Sep 24 '22 21:09 Leksat

@Leksat Thanks rdev worked for me! I see what you mean about it having other issues though.

cppxor2arr avatar Sep 25 '22 10:09 cppxor2arr