emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: sit-for and idle timers


From: Richard Stallman
Subject: Re: sit-for and idle timers
Date: Mon, 14 Aug 2006 15:20:49 -0400

    The change to sit-for of 2006-07-26 ("Use new SECONDS arg of read-event
    instead of a timer") seems to cause problems with idle-timers
    which call sit-for.


Why do these timer functions call sit-for?  It is a strange thing for
a timer to wait.  It should reschedule itself instead.  What are they
really trying to do?

    > The problem is that read-event's call tree ultimately results in
    > calling keyboard.c:read_char, which calls timer_start_idle.  This
    > resets the activation time for all the current idle timer events,
    > which means that any function on an idle timer which calls sit-for
    > is now getting scheduled to be run recursively if another interval
    > of the appropriate length ensues.

    I think the solution is to avoid calling timer_start_idle when
    read-event is given a non-nil SECONDS argument.  What do people think?

That is definitely not right.  Emacs really is idle when it reads an event,
even if there is a timeout.

The way to find the right fix is to ask WHY the current behavior is
wrong.  Calling timer_start_idle is appropriate when Emacs changes
from non-idle to idle.  It is wrong to call that function when Emacs
is already idle.

So my conclusion is that when read-event is called from an idle timer,
it should not change the state to idle at the beginning, and it should
not change the state away from idle at the end.


Does this change fix it?


*** keyboard.c  12 Aug 2006 17:31:29 -0400      1.866
--- keyboard.c  14 Aug 2006 03:48:20 -0400      
***************
*** 2416,2421 ****
--- 2416,2424 ----
    volatile int reread;
    struct gcpro gcpro1, gcpro2;
    int polling_stopped_here = 0;
+   /* If we are already in the idle state, for instance if we
+      are calling from an idle timer, stay idle when we exit.  */
+   int already_idle = ! EMACS_TIME_NEG_P (timer_idleness_start_time);
  
    also_record = Qnil;
  
***************
*** 2679,2685 ****
        goto non_reread;
      }
  
!   timer_start_idle ();
  
    /* If in middle of key sequence and minibuffer not active,
       start echoing if enough time elapses.  */
--- 2682,2689 ----
        goto non_reread;
      }
  
!   if (! already_idle)
!     timer_start_idle ();
  
    /* If in middle of key sequence and minibuffer not active,
       start echoing if enough time elapses.  */
***************
*** 2749,2755 ****
        c = read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu);
  
        /* Now that we have read an event, Emacs is not idle.  */
!       timer_stop_idle ();
  
        goto exit;
      }
--- 2753,2760 ----
        c = read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu);
  
        /* Now that we have read an event, Emacs is not idle.  */
!       if (!already_idle)
!       timer_stop_idle ();
  
        goto exit;
      }
***************
*** 2931,2937 ****
  
   non_reread:
  
!   timer_stop_idle ();
    RESUME_POLLING;
  
    if (NILP (c))
--- 2936,2943 ----
  
   non_reread:
  
!   if (!already_idle)
!     timer_stop_idle ();
    RESUME_POLLING;
  
    if (NILP (c))
***************
*** 2970,2976 ****
           prevents automatic window selection (under
           mouse_autoselect_window from acting as a real input event, for
           example banishing the mouse under mouse-avoidance-mode.  */
!       timer_resume_idle ();
  
        /* Resume allowing input from any kboard, if that was true before.  */
        if (!was_locked)
--- 2976,2983 ----
           prevents automatic window selection (under
           mouse_autoselect_window from acting as a real input event, for
           example banishing the mouse under mouse-avoidance-mode.  */
!       if (!already_idle)
!         timer_resume_idle ();
  
        /* Resume allowing input from any kboard, if that was true before.  */
        if (!was_locked)
***************
*** 3170,3177 ****
  
        show_help_echo (help, window, object, position, 0);
  
!       /* We stopped being idle for this event; undo that.  */
!       timer_resume_idle ();
        goto retry;
      }
  
--- 3177,3185 ----
  
        show_help_echo (help, window, object, position, 0);
  
!       /* If we stopped being idle for this event, undo that.  */
!       if (!already_idle)
!       timer_resume_idle ();
        goto retry;
      }
  




reply via email to

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