0

I'm new to Rust and wanted some help because I can't figure out why this simple code is not working.

I'm using rdev library and I'm just trying to store the typed key in a buffer and delete the last letter when I press backspace key.

What is weird is that the backspace key trigger correctly but nothing happen when pop() method is called, thus I'm wondering what's wrong here?

.clear() method seems to work correctly.

I'm using rdev = "0.5.2"

use rdev::{listen, Event, EventType, Key};
use std::sync::{Arc, Mutex};

#[derive(Default)]
struct AppState {
    buffer: String,
}

fn handle_key(app_state: &mut AppState, event: &Event) {            
    if let Some(ref string) = event.name  {
            app_state.buffer.push_str(string);
    }
    else if let EventType::KeyRelease(key) = event.event_type {
        if key == Key::Backspace {
            app_state.buffer.pop();
        }
        if key == Key::Escape {
            app_state.buffer.clear()
        }
        println!("buffer : {}", app_state.buffer);
    }
}

#[tokio::main]
async fn main() {
    let app_state = Arc::new(Mutex::new(AppState::default()));

    let callback = {
        move |event: Event| {
            let mut app_state = app_state.lock().unwrap();
            handle_key(&mut app_state, &event);
        }
    };

    if let Err(error) = listen(callback) {
        println!("Error: {:?}", error)
    }

}

Thank you for you help regarding this. Also if you think there is a better way to store the pressed keys let me know. Maybe there's a way to store the key and check if the user delete not only the last key but maybe also keys that are in a middle of a word for example.

1020rpz
  • 914
  • 10
  • 21
  • For debugging, I would print out the character that is returned by `pop()`. I have a feeling you are getting more characters pushed into your buffer than you expect. This would result in `pop()` is still popping off characters, but not the characters you are expecting. – effect Mar 31 '23 at 17:34

1 Answers1

1

Actually buffer.pop is working, but the problem is with the backspace. According to your logic, when you press backspace, a KeyPress event with backspace (Ascii code 08) arrives and gets inserted to the buffer first. Then when you release the key, your code handles KeyRelease separately and that is where you pop that last 08 back.

You can either double pop with backspace, or try to avoid inserting a string when backspace is pressed.

Double pop: If you add a second pop operation, you will get what you want:

   ...
   ...
   if key == Key::Backspace {
      let c = app_state.buffer.pop();
      println!("C: {:#?}", c.unwrap());
      let c = app_state.buffer.pop();
      println!("C: {:#?}", c.unwrap());
    }
   ...
   ...

Or a better alternative:

Avoid backspace being inserted to the buffer:


   ...
   ...
fn handle_key(app_state: &mut AppState, event: &Event) {
  if let Some(ref string) = event.name  {
    if "\u{0008}" != string {
      app_state.buffer.push_str(string);
    }
  }
  ...

A third approach would be to refactor your code to handle KeyPress as well and insert the character if its a printable character and avoid the rest..

yerlilbilgin
  • 3,041
  • 2
  • 26
  • 21