How to read any keypress in interactive R (e.g. cursor-up or shift)? - r

How do you read any arbitrary keypress in R (interactive-mode), such as cursor-up or shift, and return the actual key(s) pressed?
Ideally in a device-independent, OS-independent way (I'm on Mac OS 10.8.x)
I'm talking about reading any actual arbitrary keypress including cursor-keys or modifier-keys, so scan() and readline() won't do it - cursor-keys get intercepted by the interactive console. And not just waiting for a keypress.
It's not clear this is easy or device-independent. I looked at documentation:
interactive(), options('device'), R_INTERACTIVE_DEVICE, R_DEFAULT_DEVICE
I read R-internals, which says "a graphics device... can handle requests/opportunities to take action such as... wait for an event, for example a mouse click or keypress." but it doesn't say much more.
I tried grDevices::getGraphicsEvent() but got:
> getGraphicsEvent('waiting for cursor keys', onKeybd=function(key) { print(key) } )
Error in setGraphicsEventEnv(which, as.environment(list(...))) :
this graphics device does not support event handling
It seems like if you dig deep enough you could use a toolkit-specific and/or OS-specific hack, e.g. with Quartz. This guy suggests Sudoku::playSudoku(), which uses Quartz to handle mouse and key input. I have Quartz. But a Quartz-specific solution won't work on Windows. This all seems quite messy.
Can someone please demystify all this?

Related

Raspberry PI GPIO Keyboard/Mouse Input

Trying to create very simple keyboard and mouse controller using the Raspberry Pi's GPIO pins. Would love to use the code in a educational setting, so trying to build super easy, readable code for children/students. But the code is acting somewhat strange, it keeps outputting the same keystrokes:
import gpiozero
from pynput.mouse import Button, Controller as MouseController
from pynput.keyboard import Key, Controller as KeyboardController
keyboard = KeyboardController()
mouse = MouseController()
Up = gpiozero.Button(26, bounce_time=0.02)
LeftMouse = gpiozero.Button(17, bounce_time=0.02)
while True:
if Up.is_pressed:
print("Up")
keyboard.press(Key.up)
Up.wait_for_release()
keyboard.release(Key.up)
elif LeftMouse.is_pressed:
print("Left Mouse button")
mouse.press(button.left)
LeftMouse.wait_for_release()
mouse.release(button.left)
Using Python 3.7.3. No matter which GPIO I trigger (26 or 17), the code always outputs 'Up' and press the keyboard 'up' button. It must be something stupid, but I can't seem to figure it out. Would love to keep using the if/elif, so I can expand the code later with more GPIO buttons. Any idea's anyone?
Although I am not very experienced in the GPIO of Raspberry, I think your code is almost alright. I suspected that the reason of always having 'Up' outcomes, which meant the 2nd mouse condition statement was bypass, was probably due to the word 'button' being not consistent with the module you called in the first line? Below is the one after using 'Button' throughout. Probably when you triggered pin 17, it did pass through the printing stage but it could not penetrate further. It will no choice but to select the first keyboard statement. So, it would end up with 'Up' all the way.
from pynput.mouse import Button, Controller as MouseController
elif LeftMouse.is_pressed:
print("Left Mouse button")
mouse.press(Button.left)
LeftMouse.wait_for_release()
mouse.release(Button.left)
I also found the below link quite useful in order to make sure the packages imported and defined properly.
pynput - Importing keyboard and mouse
Looking forward to hearing from your update.

How am I sure that my process has a user interface?

When running a class which can be used interactively or silently by batch, I want to display a hourglass, only if in interactive mode.
I found the function xGlobal::clientKind() , read below, but not sure it is sufficient (can't batches also run on Client ?)
if (xGlobal::clientKind() == ClientType::Client)
startLengthyOperation();
// here do the process
if (xGlobal::clientKind() == ClientType::Client)
endLengthyOperation();
Do not bother to test client kind when using startLengthyOperation, the method does a sufficient test itself.
Testing should be like this:
if (clientKind() == ClientType::Client)
...
Don't use xGlobal::clientKind, use without qualification.
The ClientType has four values, matching what you see in "Online Users".
Batch can be called interactively in Basic/Periodic/Batch, but it should be rarely used.

Client doesn't have a name/class at startup

I'm trying to start an application (Spotify) on a particular tag. Rules aren't applied and now I'm inspecting the client class by printing the class in a notification in the "manage" signal. This results in an empty notification.
client.connect_signal("manage", function (c, startup)
naughty.notify({title=c.class})
end)
When I restart awesome, it does print the client class, so why isn't it working when the client is initially started?
Using xprop, it also prints the class:
WM_CLASS(STRING) = "spotify", "Spotify"
Sounds like a bug in Spotify (and I think I heard about this one before). I would guess that Spotify does not follow ICCCM and only sets its WM_CLASS property after it made its window visible and not before.
I fear that you cannot do much about this except for complaining to Spotify devs to fix their stuff.
You could work around this by starting a timer in the manage signal that checks if a window turns out to be spotify a short time later. Alternatively, you could do something like client.connect_signal("property::class", function(c) if c.class == "Spotify" then print("This is now a spotify window") end end) to react to change to a window's class (of course you'd want to do something more useful to Spotify's windows than printing them).
(Per the ICCCM, a window is not allowed to change its class while it is visible, but who cares about standards...)
I had a similar issue with the claws-mail client. Inspecting it via xprop, it shows
WM_CLASS(STRING) = "claws-mail", "Claws-mail"
but awesome just did’t apply the rules for it. The trick was giving awesome-wm both of these class names in the rules section by providing a set of characters to chose from:
rule = {class = "[Cc]laws%-mail"}
I hope this works for your spotify application, too.
For further reading about patterns in lua I suggest this:
https://www.lua.org/pil/20.2.html

PostMessage interferes with user input

I'm trying to send key stroke to an external application in java using jna.
It sends VK_DOWN key, also that application has a shortcut for ctrl+down which makes something very different. My application sends around ~15 down key with 1 sec in between, and if user happens to click CTRL during it while working on a different window, it breaks the application(treats it as ctrl+down).
I checked the keyboard messages via Spy++, compared mine with AutoIt, they are exactly same messages.
ControlSend("window_title", "", "", "{DOWN}")
This AutoIt code works perfect, even if I click ctrl when window is active or inactive, it does not interfere with down key.
My code on the other hand:
User32.INSTANCE.PostMessage(handle, WM_KEYDOWN, wparam, lparamDown);
User32.INSTANCE.PostMessage(handle, WM_KEYUP, wparam, lparamUp);
has exactly same messages, but it doesn't work.
I tried sending control up before sending down key but to no avail.
Spy++ output:
<14335> 00011456 P WM_KEYDOWN nVirtKey:VK_DOWN cRepeat:1 ScanCode:50 fExtended:1 fAltDown:0 fRepeat:0 fUp:0
<14336> 00011456 P WM_KEYUP nVirtKey:VK_DOWN cRepeat:1 ScanCode:50 fExtended:1 fAltDown:0 fRepeat:1 fUp:1
My ctrl clicks are not even on target application so why does it treat it as such? Should I use a hook?

When listening for keypress in Flash Lite should I be listening for Key.Down or the numeric code for this key?

The adobe documentation says that when listening for a keypress event from a phone you should listen for Key.Down, however when I trace the Key.getCode() of keypresses I see a number not the string "Key.Down". I am tesing this locally in device central and do not have a phone to test this with at present. Here is my code -
keyListener = new Object();
keyListener.onKeyDown = function() {
switch (Key.getCode()) {
trace(Key.getCode()) // outputs 40
case (Key.DOWN) : // according to the docs
pressDown();
break;
}
}
My question is - is this simply because Im testing in device central and when I run it on the phone I will need to be listening for Key.Down? or is the documentation wrong? Also is the numeric code (40) consistent across all devices? What gives adobe?
thanks all
Key.Down is equal to 40 so it will recognize it as the same. So you can use whichever one you prefer, however, I would recommend using Key.Down because it will be easily recognizeable for those who dont have Key Codes memorized (most of us).
These are the Key Code Values for Javascript. However, I think they are pretty much universal

Resources