read keyboard input on background thread

this saves a lot of cpu compared to polling