I ran through some tests, and I see you have run through them too, because it all looks very solid. Great!
Minor bugs I see:
When waiting for unicode character input, typing a character above 0xFF does not trigger the event. (Typing option-p for “π” on a Mac keyboard, for example.)
(When waiting for non-unicode character input, it’s arguably okay to ignore such characters. Or you could trigger an event and return “?”.)
Writing files by name puts them in the user’s home directory, which is bad form. (On MacOS – it’s probably the current working directory.) Better to have some Mac/Win/Linux-specific code to select an appropriate library directory.