diff --git a/src/demo/demo.h b/src/demo/demo.h index ce7f23392a..05cdbe4e94 100644 --- a/src/demo/demo.h +++ b/src/demo/demo.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -146,6 +147,9 @@ int demo_render(struct notcurses* nc); #define DEMO_RENDER(nc) { int demo_render_err = demo_render(nc); if(demo_render_err){ return demo_render_err; }} +// locked by callers to notcurses_render() and notcurses_refresh(), all internal +extern pthread_mutex_t demo_render_lock; + // if you won't be doing things, and it's a long sleep, consider using // demo_nanosleep(). it updates the HUD, which looks better to the user. int demo_nanosleep(struct notcurses* nc, const struct timespec *ts); diff --git a/src/demo/hud.c b/src/demo/hud.c index 3f85c29f24..fac4551ab5 100644 --- a/src/demo/hud.c +++ b/src/demo/hud.c @@ -5,6 +5,8 @@ // their mouse. it should always be on the top of the z-stack. struct ncplane* hud = NULL; +pthread_mutex_t demo_render_lock = PTHREAD_MUTEX_INITIALIZER; + // while the HUD is grabbed by the mouse, these are set to the position where // the grab started. they are reset once the HUD is released. static int hud_grab_x = -1; @@ -438,5 +440,9 @@ int demo_render(struct notcurses* nc){ return -1; } } - return notcurses_render(nc); + // lock against a possible notcurses_refresh() on Ctrl+L + pthread_mutex_lock(&demo_render_lock); + int ret = notcurses_render(nc); + pthread_mutex_unlock(&demo_render_lock); + return ret; } diff --git a/src/demo/input.c b/src/demo/input.c index f934f58af6..3ea5e3620f 100644 --- a/src/demo/input.c +++ b/src/demo/input.c @@ -92,16 +92,23 @@ ultramegaok_demo(void* vnc){ continue; } if(nckey_mouse_p(ni.id)){ - handle_mouse(&ni); - }else{ - // if this was about the menu or HUD, pass to them, and continue - if(menu_or_hud_key(nc, &ni)){ + if(handle_mouse(&ni)){ continue; } - // go ahead and pass keyboard through to demo, even if it was a 'q' - // (this might cause the demo to exit immediately, as is desired) - pass_along(&ni); } + if(id == 'L' && ni.ctrl){ + pthread_mutex_lock(&demo_render_lock); + notcurses_refresh(nc); + pthread_mutex_unlock(&demo_render_lock); + continue; + } + // if this was about the menu or HUD, pass to them, and continue + if(menu_or_hud_key(nc, &ni)){ + continue; + } + // go ahead and pass keyboard through to demo, even if it was a 'q' + // (this might cause the demo to exit immediately, as is desired) + pass_along(&ni); } return NULL; } diff --git a/src/lib/internal.h b/src/lib/internal.h index 05fc859d90..2fb5a8cfc0 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -179,7 +179,7 @@ typedef struct ncselector { uint64_t titlechannels; // title channels uint64_t footchannels; // secondary and footer channels uint64_t boxchannels; // border channels - int uarrowy, darrowy, arrowx;// location of scrollarrows, -1 if not present + int uarrowy, darrowy, arrowx;// location of scrollarrows, even if not present } ncselector; typedef struct ncdirect {