Skip to content

Instantly share code, notes, and snippets.

@sylt
Created November 22, 2015 20:17
Show Gist options
  • Star 33 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • 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;
}
@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