Search code examples
c++windows-subsystem-for-linuxncursestmuxwindows-terminal

ncursesw application won't catch ctrl-C/S/Z


I'm trying to create a c++ application using ncursesw.

I want to use some shortcuts for my own functions.

  1. Ctrl+C
  2. Ctrl+S
  3. Ctrl+Z

I know I can just catch the signals directly but apparently a lot of documentation is telling me that this shouldn't be necessary and that ncursesw provides this functionality. As far as I understood this, you should be able to catch those keycodes by using raw(); and enabling the keypad(stdscr, true); function. But this won't do it for me.

I am somewhat suspicious tho that there may be some other application catching those keys bevor they reach me. I am running my application inside the following stack:

  • NewWindowsTerminal
    • WSL
      • Tmux
        • zsh
          • myapp

Here is the code I use to test it:

#include <iostream>
#include <ncursesw/ncurses.h>

using namespace std;

void quit();

int main(int argc, const char *argv[])
{
    // Init Curses ----------
    setlocale(LC_ALL, "");
    WINDOW* win = initscr();
    atexit(quit);
    raw(); // disable line buffering
    curs_set(0); // hide cursor
    use_default_colors(); // enable transparent black
    start_color(); // enable color
    clear(); // clear screen
    noecho(); // disable echo
    cbreak(); // disable line buffering
    keypad(stdscr, true); // enable function keys
    mousemask(ALL_MOUSE_EVENTS, NULL); // enable mouse events
    
    // the following loop is just test code
    int input;
    do {
        input = getch();
    } while(input != 'q');
    
    return 0;
}

void quit() {
    endwin();
}

The goal with this code is to ONLY be able to exit using 'q' and not using Ctrl-C but it still exits using the Ctrl-C.

Does anyone have any idea if somewhat is causing an issue here or if its actually not even possible to catch those keys just by using the curses library?


Solution

  • OP's program has a bug, which prevents it from working as intended:

    raw(); // disable line buffering
    

    is overridden by

    cbreak(); // disable line buffering
    

    (deleting that line, the getch will return ^C, etc.)