[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: first keycode is not correct when application uses own poll
From: |
Thomas Dickey |
Subject: |
Re: first keycode is not correct when application uses own poll |
Date: |
Sun, 18 Jul 2021 18:34:39 -0400 |
User-agent: |
Mutt/1.10.1 (2018-07-13) |
On Sun, Jul 18, 2021 at 10:57:24AM +0200, Pavel Stehule wrote:
> Hi
>
> I am author of pspg https://github.com/okbob/pspg, and I found strange
> behaviour of ncurses input processing when there is a specific situation.
> a) pspg is a pager, so I need to process an reading from two streams stdin
> and tty. For this purpose I use timeout(0) and my own poll. Almost every
> time I have an active keypad, but not always - for readline is necessary
> raw stream. So I have an active keypad on stdscr and disabled keypad on my
> window that is used for editing.
yes, but: there's only one keyboard in a SCREEN, and when you call keypad,
that causes ncurses to send smkx or rmkx (unless it determines that the
keyboard is already in the requested state).
ncurses flushes the output, but that doesn't affect whatever
might be pending on the keyboard -- it only helps the terminal
to decide what to do with keys.
Switching modes on keypad is an old problem, as seen in the NEWS file:
20080524
+ modify _nc_keypad() to make it switch temporarily as needed to the
screen which must be updated.
20011218
+ correct location of call to _nc_keypad() from 20011215 changes which
prevented keypad() from being disabled (reported by Lars Hecking).
20011215
+ corrected logic of keypad() by adding internal screen state to track
whether the terminal's keypad-mode has been set. Use this in
wgetch() to update the keypad-mode according to whether the
associated window's keypad-mode has been set with keypad(). This
corrects a related problem restoring terminal state after handling
SIGTSTP (reported by Mike Castle).
I don't see a way to improve this special case.
You might be able to get more consistent results by following the first
keypad call with flushinp:
flushinp
The flushinp routine throws away any typeahead that has been typed by
the user and has not yet been read by the program.
though that applies to what's in the FIFO (still a race with the actual
terminal).
> Please, see file test-ncurses-bug
>
> When I press key down as first event, I get result
>
> pressed "^[" (27)
> pressed "[" (91)
> pressed "B" (66)
>
> instead
>
> pressed "KEY_DOWN" (258)
>
> First event is not processed correctly.
>
> Workaround is simple (but looks messy, and it was crazy to find this
> workaround) - just run again "workpad" function on stdscr
>
> It is interesting, so without a mentioned workaround, the behaviour is
> fixed by self for next key's events.
>
> Regards
>
> Pavel
> #define NCURSES_WIDECHAR 1
>
> #include <poll.h>
> #include <wchar.h>
> #include <ncursesw/ncurses.h>
>
> static struct pollfd fds[1];
>
> int
> main()
> {
> SCREEN *term;
> WINDOW *win;
> int c;
> int line = 10;
>
>
> term = newterm(termname(), stdout , stdin);
> win = newwin(5, 20, 5, 5);
>
> noecho();
> clear();
> cbreak();
> keypad(stdscr, TRUE);
> keypad(win, FALSE);
>
> /*
> * Workaround - after uncomment, the code
> * will work as expected.
> *
> keypad(stdscr, TRUE);
> */
>
> timeout(0);
>
> fds[0].fd = fileno(stdin);
> fds[0].events = POLLIN;
>
> mvprintw(8, 10, "try to press KEY DOWN (or any key or q)");
> refresh();
>
> while (1)
> {
> wint_t ch;
> int poll_num;
>
> poll_num = poll(fds, 1, -1);
>
> (void) get_wch(&ch);
>
> c = ch;
>
> if (c == 'q')
> break;
>
> mvprintw(line++, 10, "pressed \"%s\" (%d)", keyname(c), c);
> clrtoeol();
> refresh();
> }
>
> endwin();
> }
--
Thomas E. Dickey <dickey@invisible-island.net>
https://invisible-island.net
ftp://ftp.invisible-island.net
signature.asc
Description: PGP signature