bug-ncurses
[Top][All Lists]
Advanced

[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

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]