From 99007e128c0c4d62784656008ebee5de61ff060d Mon Sep 17 00:00:00 2001 From: nick black Date: Sun, 19 Sep 2021 20:13:02 -0400 Subject: [PATCH] [input] add evtype to ncinput, for press/repeat/release #2182 --- NEWS.md | 7 +++++++ USAGE.md | 7 ++++++- doc/man/man3/notcurses_input.3.md | 11 ++++++++--- include/notcurses/notcurses.h | 30 ++++++++++++++++++----------- python/examples/006-input-tester.py | 1 - src/lib/in.c | 3 --- 6 files changed, 40 insertions(+), 19 deletions(-) diff --git a/NEWS.md b/NEWS.md index 02a470433..940d3e05f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,6 +12,13 @@ rearrangements of Notcurses. retrieve terminal messages (if buffers are full, Notcurses cannot continue reading). Likewise added `NCDIRECT_OPTION_DRAIN_INPUT`. * Removed a bunch of deprecated `static inline` functions from the headers. + * A new field, `evtype`, has been added to `ncinput`. It takes a value + from among `EVTYPE_{UNKNOWN, PRESS, REPEAT, RELEASE}.`. Where possible, + Notcurses will distinguish between a press, repeat, and release. This + cannot be done in all environments, nor with all inputs. The + `NCKEY_RELEASE` definition is no longer returned; instead, the + appropriate `NCKEY_BUTTONx` synthesized key is returned, with + `EVTYPE_RELEASE` set. * 2.4.1 (2021-09-12) * `notcurses_check_pixel_support()` still returns 0 if there is no support diff --git a/USAGE.md b/USAGE.md index 293faaf25..0882bceeb 100644 --- a/USAGE.md +++ b/USAGE.md @@ -684,7 +684,12 @@ typedef struct ncinput { bool alt; // was alt held? bool shift; // was shift held? bool ctrl; // was ctrl held? - uint64_t seqnum; // input event number + enum { + EVTYPE_UNKNOWN, + EVTYPE_PRESS, + EVTYPE_REPEAT, + EVTYPE_RELEASE, + } evtype; } ncinput; // Read a UTF-32-encoded Unicode codepoint from input. This might only be part diff --git a/doc/man/man3/notcurses_input.3.md b/doc/man/man3/notcurses_input.3.md index 99b5ad7ea..b5a6e59c6 100644 --- a/doc/man/man3/notcurses_input.3.md +++ b/doc/man/man3/notcurses_input.3.md @@ -21,7 +21,12 @@ typedef struct ncinput { bool alt; // Was Alt held during the event? bool shift; // Was Shift held during the event? bool ctrl; // Was Ctrl held during the event? - uint64_t seqnum; // Monotonically increasing input event counter + enum { + EVTYPE_UNKNOWN, + EVTYPE_PRESS, + EVTYPE_REPEAT, + EVTYPE_RELEASE, + } evtype; } ncinput; ``` @@ -77,8 +82,8 @@ be the actual input file descriptor. If it readable, **notcurses_get** can be called without the possibility of blocking. **ncinput_equal_p** compares two **ncinput** structs for data equality (i.e. -not considering padding or the **seqnum** field), returning **true** if they -represent the same input (though not necessarily the same input event). +not considering padding), returning **true** if they represent the same +input (though not necessarily the same input event). **notcurses_linesigs_disable** disables conversion of inputs **INTR**, **QUIT**, **SUSP**, and **DSUSP** into **SIGINT**, **SIGQUIT**, and **SIGTSTP**. These diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index 7e28d5c43..c4bb09f0e 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -1037,19 +1037,25 @@ nckey_mouse_p(uint32_t r){ return r >= NCKEY_BUTTON1 && r <= NCKEY_RELEASE; } -// An input event. Cell coordinates are currently defined only for mouse events. +// An input event. Cell coordinates are currently defined only for mouse +// events. It is not guaranteed that we can set the modifiers for a given +// ncinput. We encompass single Unicode codepoints, not complete EGCs. typedef struct ncinput { - uint32_t id; // identifier. Unicode codepoint or synthesized NCKEY event - int y; // y cell coordinate of event, -1 for undefined - int x; // x cell coordinate of event, -1 for undefined - bool alt; // was alt held? - bool shift; // was shift held? - bool ctrl; // was ctrl held? - uint64_t seqnum; // input event number + uint32_t id; // Unicode codepoint or synthesized NCKEY event + int y; // y cell coordinate of event, -1 for undefined + int x; // x cell coordinate of event, -1 for undefined + bool alt; // was alt held? + bool shift; // was shift held? + bool ctrl; // was ctrl held? + enum { + EVTYPE_UNKNOWN, + EVTYPE_PRESS, + EVTYPE_REPEAT, + EVTYPE_RELEASE, + } evtype; } ncinput; -// compare two ncinput structs for data equality. we can't just use memcmp() -// due to potential padding in the struct (especially wrt bools) and seqnum. +// compare two ncinput structs for data equality. static inline bool ncinput_equal_p(const ncinput* n1, const ncinput* n2){ if(n1->id != n2->id){ @@ -1061,7 +1067,9 @@ ncinput_equal_p(const ncinput* n1, const ncinput* n2){ if(n1->alt != n2->alt || n1->shift != n2->shift || n1->ctrl != n2->ctrl){ return false; } - // do not check seqnum! + if(n1->keytype != n2->keytype){ + return false; + } return true; } diff --git a/python/examples/006-input-tester.py b/python/examples/006-input-tester.py index d62b4cc2e..6e367bed4 100644 --- a/python/examples/006-input-tester.py +++ b/python/examples/006-input-tester.py @@ -35,7 +35,6 @@ while True: std_plane.putstr(f"Is alt: {p.is_alt}", y_pos=3, x_pos=0) std_plane.putstr(f"Is shift: {p.is_shift}", y_pos=4, x_pos=0) std_plane.putstr(f"Is ctrl: {p.is_ctrl}", y_pos=5, x_pos=0) - std_plane.putstr(f"Seqnum: {p.seqnum}", y_pos=6, x_pos=0) std_plane.putstr("Press CTRL+C to exit.", y_pos=7, x_pos=0) std_plane.context.render() diff --git a/src/lib/in.c b/src/lib/in.c index 80d56e89c..606e788db 100644 --- a/src/lib/in.c +++ b/src/lib/in.c @@ -125,7 +125,6 @@ typedef struct inputctx { HANDLE stdinhandle; // handle to input terminal for MSFT Terminal #endif - uint64_t seqnum; // process-scope sequence number int lmargin, tmargin; // margins in use at left and top struct esctrie* inputescapes; @@ -473,7 +472,6 @@ create_inputctx(tinfo* ti, FILE* infp, int lmargin, int tmargin, i->runstring[i->stridx] = '\0'; i->lmargin = lmargin; i->tmargin = tmargin; - i->seqnum = 0; i->drain = drain; logdebug("input descriptors: %d/%d\n", i->stdinfd, i->termfd); return i; @@ -2013,7 +2011,6 @@ internal_get(inputctx* ictx, const struct timespec* ts, ncinput* ni){ id = ictx->inputs[ictx->iread].id; if(ni){ memcpy(ni, &ictx->inputs[ictx->iread], sizeof(*ni)); - ni->seqnum = ++ictx->seqnum; } if(++ictx->iread == ictx->isize){ ictx->iread = 0;