How to implement proper mouse support in a terminal / terminfo entry? - ncurses

I've implemented a terminal emulator and a corresponding terminfo entry that allows me to run ncurses programs like emacs, mc (midnight commander) or tig (git browser). I want to add mouse support to the terminal, most notably to position the cursor in emacs by clicking into the window. After a lot of googling and some help on stackoverflow I learned about the required terminfo fields (most notably kmous) and control (e.g. \E[?1000h) and "key" (\E[M...) sequences and implemented mouse button events in my terminal. I've written a small ncurses program that goes something like this:
initscr ();
clear ();
noecho ();
cbreak ();
keypad (stdscr, TRUE);
mousemask (ALL_MOUSE_EVENT, NULL);
if (has_mouse ())
{
while (1)
{
switch (getch ())
{
case KEY_MOUSE:
if (getmouse (&event) == OK)
{
printf ("mouse event 0x%x at %i,%i\n", event.bstate, event.x, event.y);
This program works fine on xterm and my terminal, so both my terminal and its terminfo entry can't be completely wrong.
However, mc appears to not recognize mouse support in my terminal, does not even issue any \E[?1000h sequence to activate it and is therefore utterly confused by the mouse button events my terminal sends (even without \E[?1000hactivation).
What am I missing?

Someone pointed out this problem recently (though the question was not mentioned):
20181124
+ modify the initialization checks for mouse so that the xterm+sm+1006
block will work with terminal descriptions not mentioning xterm
(report by Tomas Janousek).
The problem was that the code would use the kmous capability if TERM had "xterm", and otherwise would default to the original xterm mouse protocol (which didn't have "any event" capability). That probably was overlooked for quite a while due to inertia (people using the "xterm" terminal descriptions with other terminals).
The ncurses manual page does say what's intended:
Because there are no standard terminal responses that would serve to
identify terminals which support the xterm mouse protocol, ncurses assumes that if your $TERM environment variable contains "xterm", or
kmous is defined in the terminal description, then the terminal may
send mouse events.

Related

Linux command line application with persistent interface

How do programs (specifically in Linux) like top keep their interface on the screen without it scrolling? Do they create a new screen session, or is there a standard library for creating GUIs like that? If they do use screen, then why is the output still written to stdout when I exit top?
There is a standard library, it is called ncurses. But there's no need to use it - the console_codes(4) man page describes how to do such things by writing special character sequences to a terminal (emulator), and curses is nothing but a wrapper around that.
To clear the screen like top does, you'll need to echo ESC [ 2 J to the terminal to clear it, followed by ESC [ H to reset the cursor to the origin, i.e.
echo -ne "\033[2J\033[H"
Note that top might actually be more intelligent and not redraw the entire screen but only the parts which changed. See the manual page for more details. (You can do more fancy stuff with console codes, like changing colors, underline, bold, or even use the mouse in x terminals.)

Can't write English in xterm terminal

My keyboard has two languages, English and other. But in xterm I can write only in other language, and I can't replace the language in any way (alt-lshift, the regular way, or in the gui). With shift key I can write upper case (with caps lock it doesn’t work).
The Cygwin guides on the internet referrals me to xkb layout files, that doesn't existing in my computer at all.
I open the xterm from the icon of Xwin.
Thank you.
Since this is an XTerm running in the Cygwin X server, the X server is doing all the keyboard input translation, independently from the keyboard translation Windows does for other programs (the X server reads the raw keyboard input from the device). So you have to use the X11 methods of changing keyboard layouts. Into your .xinitrc or .xprofile (I can't remember which one Cygwin uses) put the following command
setxkbmap us
To load the US keyboard layout. You can type it also from your xterm when you need it. Read the manpage of setxbmap for details.

Focus follow mouse in vim

I am aware that the mousefocus option is only supposed to work in gVim. But I was wondering, if it's possible to have the console Vim switch to different windows in response to mouse clicks, would it be not possible to easily add following mouse movement to it, too?
I'm an xmonad user, I love the focus following the pointer feature, I do a lot of pdf viewing and browsing while writing in Vim, and I'd be so much happier if I didn't have to keep mentally switching back and forth between two different types of focus changing.
If that's completely not possible, I guess opening new Vim windows (as with :split) in new instances of the terminal is no easier to do?
It would not be at all simple to add this. Using the mouse within the terminal works by vim sending control codes to the terminal requesting that mouse actions be sent as part of the input stream. Terminals only report clicks not changes in the pointer position, so vim has no way of knowing where the mouse is.
With major changes it would likely be possible for a vim with X support to get pointer activity directly from the X server, but that would likely be reported by pixel rather than by character so further work would need to be done before it could determine which vim window is currently under the pointer.
set mouse=a
should do the trick but it will probably depend on your terminal emulator. See :help 'mouse'.
This works for Windows 7/Cygwin 32bit mintty/vim 7.3: (I DO NOT use gvim!)
Having installed this: http://ehiti.de/katmouse/, I can scroll the window under my cursor without having to have clicked to select a window, click-selecting of single vim-windows works, too. It does not pull the vim window to the foreground, if another window overlaps it, if that is what you desire. Still it can be scrolled without click-selecting it first.
So:
Check if there exists a software paket for your distribution, that implements your desired mouse behavior on the OS level. When this works for my self-compiled vim in cygwin, it might very well work with console vim on linux, too.
This post here serves as evidence, that it is possible at all, that is the reason this was not made a comment. When I am on linux again I will investigate this further and update this post, but that might take a while.
On set mouse=a: The vim help states you a need a terminal capable of handling mouse inputs, further information can be found here. :help ttymouse might also be helpful, i.e. if you have a xterm-compliant console, but :help term is set to something else.
UPDATE: (Freshly installed Fedora 19 with packages, no self-compiled stuff.)
Fedora 19 + se mouse=a = scrolling in single console vim window with several buffers opened next to each other independently works, too. Window manager used is LXDE.

Why does vim connect to X by default?

The man page says vim -X disables clipboard and window title operation. Is that all we get for vim connecting to X?
I find it a bit surprising, since the default settings slow down vim's startup significantly for me, and I've never needed the clipboard/window title behavior.
This is not gvim, by the way.
My educated guess would be, that it's because most people nowadays use terminal emulators in graphical environments, so it would be useful to behave like nice citizen of such an environment, providing more of a consistency in how various applications look or work.
As a bonus it's more vim-like to use * register for interrogating clipboard.
And more foolproof. I remember graphical terminal emulators where the only way to select text was the old fashioned mouse selection. Given that vim buffer in terminal would not scroll when you selected part of the terminal (as technically selection occurred outside vim in the realm of terminal emulator, and vim was not even aware it's currently taking place) it would not be possible to copy to clipboard anything spanning more than screen could currently hold. And even then it might not work the way you'd want depending on line wrapping settings.
But that is not the problem if editor has connection to system clipboard. Just copy any text you like to * register in the vim-way, and then you have it in system clipboard.
It's still just my speculation.

Cygwin non-US or indirect characters don't work in xterm on extra monitor

I have run into this freaky thing in two places now, on a Windows 7 and an XP machine.
I have a laptop with an extra monitor connected. I start up cygwin's x-server, using the start menu shortcut (Cygwin-X/XWin Server). I then start an xterm by right-click the X icon in the icon tray at the bottom right, and selecting Applications/xterm.
I get an xterm. In it I can type text, but depending on which monitor the xterm window resides, all characters that require two keypresses on my swedish keyboard (example: "~" requires me to first press alt+the key marked "^ ¨ ~" and then press space, rendering a single ~ on the screen) result in a space being printed.
If I move the xterm to the other monitor, I am suddenly able to type a ~ in the xterm. Move it back to the previous monitor, and I can't type ~ anymore.
Weird or what? This is the problem I have now, on my XP laptop. On my Windows7 laptop (same basic setup) I had the problem that I could only type stuff like åäö (not indirect/combined characters - I have keys marked å, ä and ö respectively on my keyboard) on one monitor, not the other.
I have messed around with different ways to start up the X Server, I think I am doing it the right way as I describe here.
My cygwin installation is maybe a year old on both machines. I would like to be able to find whatever setting causes this behaviour, so I can handle it should I come across similar problems in the future.
Any ideas?
Edit: some stuff that looked like html tags got mangled.
Since this seems to be a problem only with xterm, as a simple workaround I would suggest using some other terminal emulator instead of xterm. On Cygwin, a really nice substitute is mintty (available as a Cygwin package from within Cygwin setup). I stopped using xterm in favor of mintty some time ago because I found it to simply be an all-around more useful terminal emulator.
As a possible side benefit of using mintty, if xterm is the only X application you typically use, then you don't even need to run an X server any more because mintty is not an X application.

Resources