Mouse support with ncurses (for python) for large terminals - python-3.x

I'm using python3 with ncurses (curses) inside a docker container.
The problem is that mouse events are not accurately reporting x position in terminals that have more than 222 cells width. At first glance this is an obvious limitation because as far as i can see the position is sent in a single byte.
However Midnight Commander accurately handles large terminals. After some digging i could not find how to properly handle mouse with curses (this example does not work properly). Everything i tried with curses failed to work with large terminals. It seems that midnight commander is using gpm, but i could not find any way to use that in python.
q1: How can i handle mouse in large terminals in python3 directly, preferably with curses?
q2: Taking midnight commander as an example, will printing the escape sequences directly in stdout make the mouse work as expected ?
q3: Is there any other terminal gui library that handles mouse properly for python ?

It's not a direct limitation of the python interface to curses, but rather a feature of the underlying curses library, terminal description and the terminal:
For ncurses, that's the extended mouse feature which is standard in ncurses with ABI 6 (available since 2005, standard in ncurses 6 in 2015), noting that some distributions still provide ABI 5.
The terminal description has to use a feature which ncurses recognizes as implying the support for SGR 1006, and of course
The terminal itself has to support that feature (see note in ncurses database from January 2018 pointing out a few of the xterm imitators which do not).

Related

PyQT5 different view on OS and Linux

I created a python program that uses PyQT5, but looking at the displayed windows on Mac OS X and Linux then they differentiate quite a bit.
Here is the MAC OS X window
And here is the Linux version:
As you can see, the alignment of the tabs and the size/alignment of single lineedits is quite different. I understand that the rendering of the window depends on the underlying operating system, but is there any way to force the system to produce a similar output for all, e.g.:
Put the tabs to the very left
Make Lineedits be window width (or whatever size they were set to)
Qt5 has a platform-independent style plugin, fusion. Set the application to use this style, and it will look exactly the same on all platforms.
You can do this either by using Python code, calling QApplication.setStyle(), with an instance of QFusionStyle; or by setting the QT_STYLE_OVERRIDE environment variable to fusion; or by passing -style fusion as command line arguments to the application.
It is a decent style in my opinion, however, it doesn't feel entirely "native" anywhere.

How does tmux, vim, emacs, etc transcend the UI limitations of *nix terminals?

When I'm writing a program for use on the command line, I notice that there's some limitations. For instance, I can't draw a 1-pixel-thick horizontal or vertical line like tmux does when it separates panes in a window. I can only move the cursor down, not up like VI seemingly does. I can't refresh information on the top of the page if the cursor is at the bottom.
So, when programs like tmux and vi do this, I have to wonder if they are:
drawing the screen from top to bottom every update (which I think is highly unlikely because otherwise I could scroll up in my terminal and see each redraw)
using some library that enables graphics in the terminal, like SDL, which I also think is unlikely.
using some standard syscall I don't know about
or finally
taking advantage of some feature of Linux/Unix of which I'm completely unaware.
So, how do these programs generate such a rich UI in such a seemingly limited shell? So long as the answer gives me just enough fodder to go on a Google rampage, I'll be happy.
I'm also assuming that these programs use some common method to do these things, but if that's wrong let me know.
A typical terminal emulator has a lot more features than are immediately apparent.
Essentially a program just needs to output short sequences of bytes that represent various commands such as move cursor (up|down|left|right), change color, scroll region, erase region, etc.
These commands typically begin with the escape character (the same character that is generated when you press the esc key while typing in a terminal) followed by various other characters, depending on which action is desired.
A good starting point for understanding how it works would be the Wikipedia Article about ANSI escape codes
You can do it by hand by putting the terminal into raw mode and writing directly to the terminal using low-level operations but the standard way to do it is to use the ncurses library.

how Font and text rendering is done in different OSes

How font rendering is done in linux, bsd, windows? how they differ?
I am not talking about browser web font rendering.say for example how input system works? I press mouse keys. they trigger evdev drivers of linux kernel, and the kernel manages the higher level ops.
low level font rendering mechanism. how freetype, pango, window manager, interact with each other. another big question? how unicode support is accomplished??
simply, when I type a character in a text editor, what are the paths does the character flow before coming into the screen. how the MS word or LibreOffice render different fonts together in single canvas??
On *nix text-rendering is done client-side nowadays which means apps use whatever lib they like best to transform unicode codepoints to pixels and feed the result to x. The actual libs used wary widely though people has been converging on fontconfig + freetype + freebidi + harfbuzz in the past years, usually accessed through pango-cairo
A summary was posted here a few years ago
http://behdad.org/text/
It's all a devilishly complex process, you have weeks of reading if you want to understand all the steps involved.
text-rendering linux fonts

Recognition of keyboard event in python

I'm a beginning programmer and i need a way to get python to recognize a keyboard event. So far i can only find these methods in vPython or tkinter, and i want to simply use the normal python shell. if anyone can help me with a module name/where i could download a module for free that would be very helpful. or simply the code if there is no need for a module.Thanks
There is no generic "keyboard event", they all depend on what your environment is.
In a terminal there are no keyboard events at all, you simply get sent text on stdin. In Windows you need to use the Win32, on Unix you need to use the X11 API and on Mac you have to use whatever OS X uses is it Cocoa?). wxPython and tkinter all work on all these platforms to provide an API that works on all of them. And the same goes for other GUI toolkits of the same sort like KDE and GTK. So you should use one of those. Which one is a matter of taste, but since tkinter is included in Python, that seems the obvious choice.
You can call the respective API's for the respective platforms directly, but it's generally not worth the trouble.

Raster graphics in xterm?

No, not ASCII graphics, see the screenshot here:
http://en.wikipedia.org/wiki/W3m
How is that even possible?
I checked the source and it only prints character sequences. However, I am unable to find any reference to graphic drawing or image embedding escape sequences in xterm documentation or elsewhere.
w3m also seems to be the only software doing this.
There are vector graphics in Tektronix emulation, but this is done in VT mode.
Maybe I am looking for the wrong thing?
Any idea?
It's a cheat.
Note that this feature works only in "supported terminals" -- and by that it meant xterm, and rendering directly on the xterm window via xv.
Or not! Just checked the sources, the file that interests us is here. It's still a hack -- via X11 and GTK!
There is MLTerm, which supports Sixel format (not ReGis commands). It's available for both Linux and Windows.
Otherwise, according to man xterm on Ubuntu 12.04, xterm supports Tektronix graphics, which (the man page does tell) use ReGIS commands or Sixel bitmap format, depending on compilation options (I believe it's Sixel for the XTerm in the Ubuntu package repository).
One thing to know, is that ReGIS is an instruction set, while Sixel is a bitmap format.
As a side note, there exists a Python package to use Sixel aware terminal emulators: PySixel.
I'm interested in the topic too, and may update this answer in the future, with other relevant terminal emulators entries.
Higher-end models of Dec VT terminals support ReGis and Sixel graphics commands. If the xterm emulation is good enough, maybe that's how it was done?
Xterm supports the sixel and ReGIS protocols which allow rendering graphics directly in the terminal using escape sequences. However, Unicode interferes with 8 bit escape sequences, so you may need to convert them to 7bit sequences.
https://en.wikipedia.org/wiki/Sixel
https://en.wikipedia.org/wiki/ReGIS

Resources