Python curses how to detect focus? - python

is there a key to detect when the terminal is focused?
For example the KEY_RESIZE is used to detect when the terminal is resized.
Thanks

There's no predefined key, but with ncurses it is possible to define keys as done in the examples xterm-1002 and xterm-1003, which use this xterm feature
xterm+focus|xterm focus-in/out event "keys",
kxIN=\E[I, kxOUT=\E[O,
documented in XTerm Control Sequences. There's no predefined keycode, but a program could
ask ncurses for the string corresponding to "kxIN" with tigetstr (noting that 0 and -1 are special values denoting failure),
tell ncurses that this is really a key that getch should report as a keycode, using define_key, and
use key_defined to retrieve the resulting keycode.
The ncurses test-program demo_defkey uses define_key and key_defined to demonstrate how to use these functions. That's in C, of course. From python that's also doable (see for example this).
Other terminals implement a subset of xterm's control sequences. OP comments about foot, which happens to recognize mode 1004 (focus in/out). One could make a customized terminal description
foot-focus|foot with focus-in/out,
use=xterm+focus, use=foot,
and use tic to compile that. (Starting with the terminal description for foot is recommended; just setting TERM=xterm-1002, etc., tends to lead to disappointment on the part of users).

Related

How do I type a numpad plus-sign (+) with `pyautogui`?

For some GUI automation, I need to send a keystroke for the numpad plus-sign. (For some silly reason, the ancient software I'm interfacing with distinguishes between the numpad plus-sign and the top-row plus-sign...)
I can use pyautogui.press('num1') to send a 1 keystroke from the numpad, but 'num+' and 'numplus', etc, don't seem to exist.
After some digging, I found that the pyautogui.platformModule contains the mappings for this. It varies based on your OS; Windows and Linux solutions are shown in the code block below -- something similar should be possible for Mac.
Similar keyboard mappings can be made for other keys. I couldn't find a good source for the Linux key mappings, but the windows ones can be found here.
import pyautogui as gui
gui.platformModule.keyboardMapping.update({'numplus':gui.platformModule._display.keysym+_to_keycode(gui.platformModule.Xlib.XK.string_to_keysym('KP_Add'))}) # Linux: KP_Add found by random googling
gui.platformModule.keyboardMapping.update({'numplus':0x6B}) # Windows: VK_ADD from https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
gui.press('numplus')
Note that pyautogui.platformModule comes from the file _pyautogui_x11 or _pyautogui_win, etc, and is just aliased to platformModule.

Python pynput not 'understanding' greek characters

Good morning,
I am using Python's 3.8 pynput (in windows 10) to get each time the character entered (in system level) and then the unicode of this character.
from pynput import keyboard
def on_press(key):
if key == keyboard.Key.esc: #if button escape is pressed close the program
listener.stop()
else: #if button escape is not pressed get the unicode code of the button-char pressed
unicode_code = ord(getattr(key, 'char', '0'))
print("The unicode is ",unicode_code)
print("The char entered is",chr(unicode_code))
controller = keyboard.Controller()
# Collect events until released
with keyboard.Listener(on_press=on_press) as listener:
listener.join()
The problem I am facing is that when I change my keyboard to greek (with shift+alt), it keeps the unicodes of the english language and not the greek ones.
You can see the screenshot attached to understand better.
What to do to overcome this problem?
No, you aren't getting English unicode codes. You are getting unicode representation of codes returned by the keyboard. They will be the same no matter what language is chosen because keyboard layer is designed to always return same codes for same keys (by their location and/or meaning on querty/quertz or other HID compliant keyboards) if possible. What you are doing in your code is essentially reverting the process done by pynput which converts the keyboard code using char()/unichar() function. Think about it: is there a greek representation of e.g. F11 key?
I cannot remember whether pynput has higher-level inputs support or not, although I think it does. and that it should be possible to get directly what you want
What you have to do is either to find another attribute (if there is one, I am not pynput specialist) containing the character sent to the input field, or check the current keyboard language and appropriately map the codes returned. You can also try playing with codepages using the codecs module. Worst case scenario would include snatching the character directly from the GUI's input field. But that would be very inelegant, bruteforc-ish and simply the shouldn't do it thing if not strictly necessary. There are other methods for getting input from the OS - like directly linking to its event input system or kernel using built-in libraries through ctypes, wintypes, Cocoa/Carbon on Mac or GTK on Linux.
Try using pynput version 1.1.7, it works there. It is broken after 1.4 and in between these two it works, but changing the layout with the windows shortcut while the program is running, isn't working 70% of the time, meaning Windows just doesn't change the language. Alternatively, you can work around it in newer verisons by trying this solution, that converts the characters in real time if you don't care about performance. I have opened an issue for it to be fixed in the repo's github.

change color of input text using python curses

I'm developing a text game using python's wrapper library for curses.
I would like text typed in by the user to be a different color from text output by the game. I've had no problems defining color pairs for the output text, but I can't figure out how to change the input text to display different colors as the user is actively typing.
Currently, I get all input using the getstr() method.
Is this possible with python / curses?
Thanks,
Ian
While you can initialize the Python curses wrapper with echo turned on, if you are using the curses wrapper, if turns echo off initially, e.g.,
# Initialize curses
stdscr = curses.initscr()
# Turn off echoing of keys, and enter cbreak mode,
# where no buffering is performed on keyboard input
curses.noecho()
curses.cbreak()
If curses is not echoing, your program would have to be doing some echoing. But since you're using getstr, that implies you've turned echo on, since the (ncurses) manual page for getstr says
Characters input are echoed only if echo is currently on. In that case, backspace is echoed as deletion of the previous character (typically a left motion).
In this case, you could (depending on how your windows are organized) use wattrset:
Set the “background” set of attributes to attr. This set is initially 0 (no attributes).
The "background" refers to the window attributes, which are merged with attributes associated with text that's added to a window. Since getstr won't have any attributes in the text it adds, setting the window attribute "fixes" your problem. But keep in mind that you'll want to save the original attributes to restore them when getstr is done.
The ncurses curs_attr manual page explains this. The getstr function uses waddch internally (as do printw, addstr), but its manual page does not mention that.

How I can capture in Python the Ctrl key (only Ctrl, without another at the same time) when pressed?

I need to detect, in a python console (text mode) program, when the Ctrl key is pressed, without another key at the same time. I tried with getch from curses library and stdin, but it waits for any key but not Ctrl or Alt. I found information in stackoverflow but always referred to Windows/event environment, or pressed simultaneously with another key (Ctrl + C for example) but this is not my case. I have found in some forum that's no possible, but I can believe it.
This answer is Linux-centric, seeing your mention of Raspbian console mode implies a Debian GNU/Linux console system.
If you're really talking about the console, this is possible albeit very hacky. Curses has a raw mode to read most keys, but Control is a modifier key, so won't show up that way. The method I can think of is to read the input device, much like X would. Use lsinput to find which device is your keyboard. As input-events demonstrates, you can see events there while they are also processed elsewhere. Among the downsides are that you won't know if the input was actually going to you (unless you track virtual console switching, job status etc) and you need access to the device, as that property implies it might be sensitive data such as a password being entered to login on another virtual console.
It might be simpler to remap what the control key itself sends using loadkeys, thus changing it from a modifier to a detectable key. It will still retain its lower level protocol properties (in USB HID boot protocol keyboard, for instance, it will have a dedicated bit rather than use one of typically only 6 slots for pressed keys).
Either way, this is not easy or portable, and won't work at all over terminal environments such as an ssh session.

Python - detect keyboard layout

Playing around with RFID reader in serial, using python to output to console through uinput/
The thing is, doing the conversion from fake-rfid-keyboard-codes to code sent to uinput/, I would better know if I am using a QWERTY or an AZERTY ('a' becoming 'q', etc...)
Back here in Belgium, especially during the event I am working on we are highly susceptible to have both keyboard layouts, I have to support both 'on-the-fly'
Any os.*() function to do the job?
Thanx !
You could start by looking at setxkbmap -print, but generally this is nontrivial.
Why not instead set the keyboard layout to QWERTY for the virtual keyboard device you're creating with uinput? X supports separate layouts for each device.
xinput list # find the device ID, say, 12
setxkbmap -device 12 us # use it
In my experience, whenever I plug in an external USB keyboard it always starts out as US English, so I'm not sure that's even necessary.

Categories

Resources