jonder
@jonder
Изучаю с++

Почему Enter не работает в ncurses?

#include <ncurses.h>
#include <string.h>

int main()
{
    const int width = 30;
    const int height = 30;

    char menu [5][10] = {
            "[Client]",
            "[Server]",
            "[Config]",
            "[About]",
            "[Quit]"
    };

    int line = 0;

    initscr();
    start_color();
    keypad(stdscr, TRUE);

    init_pair(1, COLOR_BLUE, COLOR_WHITE);

    curs_set(0);

    int offsetx = (COLS - width) / 2;
    int offsety = (LINES - height) / 2;

    WINDOW *win = newwin(height, width, offsety, offsetx);

    box(win, 0, 0);

    while(true)
    {

        refresh();
        wrefresh(win);

        for (int i = 0; i < 5; i++)
        {
            if (line == i)
            {
                attron(COLOR_PAIR(1));
            }
            mvaddstr(LINES / 2 - 8 + i * 4, (COLS - strlen(menu[i])) / 2, menu[i]);
            attroff(COLOR_PAIR(1));
        }

        int ch = getch();
        if (ch == KEY_DOWN && line < 4) line++;
        if (ch == KEY_UP && line > 0) line--;

        if(line == 4 && ch == KEY_ENTER)
        {
            break;
        }

    }

    delwin(win);
    endwin();

Почему Enter работает только на NumPad`e?
  • Вопрос задан
  • 346 просмотров
Пригласить эксперта
Ответы на вопрос 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Почему Enter работает только на NumPad`e?

Потому что согласно man getch, ncurses использует terminfo чтобы понять, какие клавиши что делают. В частности:
Ncurses uses the terminfo definition. If it says that KEY_ENTER
is control/M, getch will return KEY_ENTER when you press control/M.

Ни в одном из файлов terminfo для терминалов которые есть у меня (screen.xterm-256color, xterm-256color) этого не сделано.

man terminfo описывает как устроены файлы terminfo, команда infocmp может быть использована для декомпиляции terminfo текущего терминала, а команда tic -- для компиляции обратно. Если сделать так:
$ infocmp > ~/tmp/terminfo
$ sed -i 's/kent=[^,]*/kent=\\r/' ~/tmp/terminfo
$ tic ~/tmp/terminfo

то твоя программа начинает работать правильно.
Но неправильно начинает работать, например, линуксовый make menuconfig -- нажатия на enter игнорируются. В коде menuconfig проверка на нажатие enter выглядит как case '\n'.

Почему так получилось и как правильно обрабатывать enter -- это два других интересных вопроса.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы