Since I want to be able to get key input in oF while typing in another window, eg. a browser, @theo suggested I look into keyloggers. I found a python script that was easy to get working. Wondering if there’s a simple way to do this in oF as well? I see that @Diederjij has a plugin from 12 years ago, but it looks like it only does capital letters for Windows:
OK, I found this simple cpp keylogger script . The key method in a Microsoft header file called “GetAsyncKeyState()”. I’ve adapted it for oF by having its main functionality in an update() instead of a while(true):
But seriously, this seems to work pretty well, don’t you think?
…gets saved like this:
BUT SERIOUSLYシ THIS SEEMS TO WORK PRETTY WELLシ DON#SHIFT#7T YOU THINK#SHIFT#
I guess the weird symbols are because I’m using a Japanese computer and converting from int to char… I guess I could add a check for certain int values and convert them to the proper string/char if I wanted the log to be a bit prettier.
There’s probably also a way to check the status of the shift key every frame to determine if something is capital/lowercase…
But since I mostly just want letters typed in another window to trigger sounds, this should be good enough for my purposes. The Python script is a little tidier, but it’s nice to not have to run a separate script simultaneously.
The logger sometimes misses keystrokes. I guess running it in update() instead of a while() loop misses some inputs depending on your timing relative to the update ticks… Any ideas for how I can fix this without being stuck in a while() loop and unable to do anything else? Maybe multithreading…?
Yeah I like the idea of trying to use an ofThread for this. An ofThread can autonomously run a while loop in the background without affecting the update/draw cycle.
Hey, that seems to work very well, thank you. How would you go about getting changes in the text file to do something in the main app? The first idea I have is to check it every update tick, count the amount of characters and, if they’re greater than the last frame, use the most recent character to do something… but there’s probably a more efficient way using Listeners or “pipes” on the threaded process itself… what would be the oF way to do this?
So using ofEvent and ofNotifyEvent inside my threaded function’s while loop doesn’t work because the recursive mutex blocks the method, so I’m doing the following, calling check() in ofApp::update():
void ofxKeyLogger::check()
{
if (isNewChar)
{
ofNotifyEvent(onNewChar, newChar);
isNewChar = false;
}
}
void ofxKeyLogger::threadedFunction()
{
while (isThreadRunning())
{
for (int KEY = 8; KEY <= 190; KEY++)
{
if (GetAsyncKeyState(KEY) == -32767)
{
if (specialKeys(KEY) == false)
{
newChar = KEY;
isNewChar = true;
}
}
}
}
}
This seems to work fine, but something tells me it’s clunky and wondering if there’s a better way.
hard to say if the GetAsyncKeyState()/specialKeys() construct is the ideal way but if you’re not missing keys your logger problem seems solved!
on a more general level you may need a form of sync for isNewChar and newChar is you might get threads conflicts (they’re rare (could happen after a duration of multiple days of running), and they’re hard to debug as the crash stack trace is not necessarily explicitly tied to the real cause). you could look into ofThreadChannel to properly “move” between threads (I find the ofxOscReceiver code a good applied model of the use). but since your data is trivial you could simply declare them atomic as std::atomic<bool> isNewChar;std::atomic<char> newChar;.