Skip to content

Instantly share code, notes, and snippets.

@sylt
Created November 22, 2015 20:17
Show Gist options
  • Save sylt/93d3f7b77e7f3a881603 to your computer and use it in GitHub Desktop.
Save sylt/93d3f7b77e7f3a881603 to your computer and use it in GitHub Desktop.
Mouse movement example for NCURSES
// I had problems getting mouse movement events working in ncurses, but after
// some research, it seems as if this is how you can do it. The magic is in the
// printf("\033[?1003h\n") which was the missing piece in the puzzle for me
// (see console_codes(4) for more information). 1003 means here that all events
// (even position updates) will be reported.
//
// This seems to work in at least three X-based terminals that I've tested:
// xterm, urxvt and gnome-terminal. It doesn't work when testing in a "normal"
// terminal, with GPM enabled. Perhaps something for the next gist version? :)
#include <curses.h>
#include <stdio.h>
int main()
{
initscr();
cbreak();
noecho();
// Enables keypad mode. This makes (at least for me) mouse events getting
// reported as KEY_MOUSE, instead as of random letters.
keypad(stdscr, TRUE);
// Don't mask any mouse events
mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL);
printf("\033[?1003h\n"); // Makes the terminal report mouse movement events
for (;;) {
int c = wgetch(stdscr);
// Exit the program on new line fed
if (c == '\n')
break;
char buffer[512];
size_t max_size = sizeof(buffer);
if (c == ERR) {
snprintf(buffer, max_size, "Nothing happened.");
}
else if (c == KEY_MOUSE) {
MEVENT event;
if (getmouse(&event) == OK) {
snprintf(buffer, max_size, "Mouse at row=%d, column=%d bstate=0x%08lx",
event.y, event.x, event.bstate);
}
else {
snprintf(buffer, max_size, "Got bad mouse event.");
}
}
else {
snprintf(buffer, max_size, "Pressed key %d (%s)", c, keyname(c));
}
move(0, 0);
insertln();
addstr(buffer);
clrtoeol();
move(0, 0);
}
printf("\033[?1003l\n"); // Disable mouse movement events, as l = low
endwin();
return 0;
}
@GaryCot
Copy link

GaryCot commented Nov 1, 2017

Best concise example of curses mouse code I have seen! Thanks for posting!
Question for you.. where did you find out what strings to printf to the xterm to turn on and off mouse movement reporting?

@TReed0803
Copy link

Thanks, this solved my troubles with ncurses mouse movement events.
Another quick tip is to set mouseinterval(0); to get snappier button press/release events.

@tva94
Copy link

tva94 commented Feb 23, 2018

Good example!

@wsxq2
Copy link

wsxq2 commented Apr 28, 2018

thanks a lot

@pabloordonez
Copy link

@GaryCot dunno where @sylt got the control sequence, but here https://www.xfree86.org/4.8.0/ctlseqs.html
the 1003 l and h are described, so that could be a place.

@SebastianRiga
Copy link

thank you for that usefull example

@AaronBottegal
Copy link

I had trouble and it turned out to be an existing nodelay and nocbreak breaking mouse reporting. Disabling both fixed my mouse reports.

@fayez-nazzal
Copy link

mouse position worked with gnome and mate terminals, but not in KDE Konsole, is there anyway to bring it to work ?

@SrinSS01
Copy link

SrinSS01 commented Feb 12, 2022

not working in windows terminal or cmd

@phoenixDownunder
Copy link

August 29th 2022, Works perfectly on Raspbian / Raspberry Pi OS Bullseye 64bit on a RPi 4
Linux RPi164 5.15.56-v8+ #1575 SMP PREEMPT Fri Jul 22 20:31:26 BST 2022 aarch64 GNU/Linux
via SSH from an Apple iMac Terminal application. Works beautifully and consistently.
Yes I want to know more about the secret activation sequence and where it is defined.
It is VERY close to standard ANSI Screen colour escape definitions... e.g.
printf(“\033[0;31m”); prints the colour red. \033[0m - default colour.

@ocertain52
Copy link

I've scoured the Internet for a working solution concerning mouse control with ncurses. This one works, none of the others do. It should not be this difficult to find working examples of ncurses. Thank you. 2023 & your solution still works.

@agvxov
Copy link

agvxov commented Sep 20, 2023

Conforming that it works with qterminal too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment