From 452f46d3665e1bfab93ec14003484ce57b636471 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Fri, 21 Jan 2022 09:15:52 +0800 Subject: [PATCH] Allow fractional values of `polling-period' This allows C-g to be handled faster in the NS port at the cost of some extra CPU time on slow machines. * etc/NEWS: Announce new feature. * src/keyboard.c (start_polling): (bind_polling_period): Handle floating point values of `polling-period'. (syms_of_keyboard): Make `polling-period' a Lisp variable instead of an int variable. --- etc/NEWS | 5 +++++ src/keyboard.c | 45 +++++++++++++++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index c6d9c32a82c..ae4bf7e4d3f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -967,6 +967,11 @@ functions. * Lisp Changes in Emacs 29.1 +-- +** The variable 'polling-period' now accepts floating point values +Setting it to a floating-point value means that Emacs will poll for +input every so many fractions of a second. + -- ** New function 'bidi-string-strip-control-characters'. This utility function is meant for displaying strings when it's diff --git a/src/keyboard.c b/src/keyboard.c index a9f3257282b..6f1614a7dfb 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1895,6 +1895,9 @@ int poll_suppress_count; static struct atimer *poll_timer; +/* The poll period that constructed this timer. */ +static Lisp_Object poll_timer_time; + #if defined CYGWIN || defined DOS_NT /* Poll for input, so that we catch a C-g if it comes in. */ void @@ -1936,17 +1939,18 @@ start_polling (void) /* If poll timer doesn't exist, or we need one with a different interval, start a new one. */ - if (poll_timer == NULL - || poll_timer->interval.tv_sec != polling_period) + if (NUMBERP (Vpolling_period) + && (poll_timer == NULL + || !Fequal (Vpolling_period, poll_timer_time))) { - time_t period = max (1, min (polling_period, TYPE_MAXIMUM (time_t))); - struct timespec interval = make_timespec (period, 0); + struct timespec interval = dtotimespec (XFLOATINT (Vpolling_period)); if (poll_timer) cancel_atimer (poll_timer); poll_timer = start_atimer (ATIMER_CONTINUOUS, interval, poll_for_input, NULL); + poll_timer_time = Vpolling_period; } /* Let the timer's callback function poll for input @@ -2014,14 +2018,28 @@ void bind_polling_period (int n) { #ifdef POLL_FOR_INPUT - intmax_t new = polling_period; + if (FIXNUMP (Vpolling_period)) + { + intmax_t new = XFIXNUM (Vpolling_period); + + if (n > new) + new = n; + + stop_other_atimers (poll_timer); + stop_polling (); + specbind (Qpolling_period, make_int (new)); + } + else if (FLOATP (Vpolling_period)) + { + double new = XFLOAT_DATA (Vpolling_period); - if (n > new) - new = n; + stop_other_atimers (poll_timer); + stop_polling (); + specbind (Qpolling_period, (n > new + ? make_int (n) + : Vpolling_period)); + } - stop_other_atimers (poll_timer); - stop_polling (); - specbind (Qpolling_period, make_int (new)); /* Start a new alarm with the new period. */ start_polling (); #endif @@ -12064,6 +12082,9 @@ syms_of_keyboard (void) help_form_saved_window_configs = Qnil; staticpro (&help_form_saved_window_configs); + poll_timer_time = Qnil; + staticpro (&poll_timer_time); + defsubr (&Scurrent_idle_time); defsubr (&Sevent_symbol_parse_modifiers); defsubr (&Sevent_convert_list); @@ -12221,12 +12242,12 @@ The value may be integer or floating point. If the value is zero, don't echo at all. */); Vecho_keystrokes = make_fixnum (1); - DEFVAR_INT ("polling-period", polling_period, + DEFVAR_LISP ("polling-period", Vpolling_period, doc: /* Interval between polling for input during Lisp execution. The reason for polling is to make C-g work to stop a running program. Polling is needed only when using X windows and SIGIO does not work. Polling is automatically disabled in all other cases. */); - polling_period = 2; + Vpolling_period = make_float (2.0); DEFVAR_LISP ("double-click-time", Vdouble_click_time, doc: /* Maximum time between mouse clicks to make a double-click. -- 2.39.5