Also in the documentation for idle timers, you can find a different approach that might work for you than the one you proposed. At the very least, your timer will fire only when Emacs is idle rather than polling for idleness. HTH.

https://www.gnu.org/software/emacs/manual/html_node/elisp/Idle-Timers.html

"Similarly, do not write an idle timer function that sets up another idle timer (including the same idle timer) with secs argument less than or equal to the current idleness time. Such a timer will run almost immediately, and continue running again and again, instead of waiting for the next time Emacs becomes idle. The correct approach is to reschedule with an appropriate increment of the current value of the idleness time, as described below."

-Stephane

On Mon, Jan 6, 2025 at 3:30 PM Jean Louis <bugs@gnu.support> wrote:
* Ship Mints <shipmints@gmail.com> [2025-01-04 20:58]:
> I believe this is intended behavior. You should use a regular interval
> timer if you want repeating executions that do not depend upon Emacs
> entering the idle state. Not sure why you think this worked differently in
> the recent past.
>
> "Emacs becomes *idle* when it starts waiting for user input (unless it
> waits for input with a timeout, see Reading One Event
> <https://www.gnu.org/software/emacs/manual/html_node/elisp/Reading-One-Event.html>),
> and it remains idle until the user provides some input. If a timer is set
> for five seconds of idleness, it runs approximately five seconds after
> Emacs first becomes idle. Even if repeat is non-nil, this timer will not
> run again as long as Emacs remains idle, because the duration of idleness
> will continue to increase and will not go down to five seconds again."

Okay I got it. Though I am surprised as I was using idle timer
thousands of times. I was thinking it repeated itself, while it
didn't.

Recently I started observing and have seen it is getting blocked, I
wondered why, due to lack of understanding.

I have found solution to my problem, so I will simply run the function
`run-with-timer` and then check if user is idle to execute it.

Basically, I do not need executions if user is not idle.

(defun my-hello ()
  (when (and (current-idle-time)
             (>= (cadr (current-idle-time)) 5))
    (rcd-message "Current idle time: %s" (cadr (current-idle-time)))))

(run-with-timer 5 5 'my-hello)

So in the sense of how I understand it, `run-with-idle-timer` only
sounds as the function I need, while it is not.

I can make it this way:

(run-with-timer 10 10 'rcd-run-repeatingly-when-idle 5 'my-hello)

(defun rcd-run-repeatingly-when-idle (secs function &rest args)
    (when (and (current-idle-time)
               (>= (cadr (current-idle-time)) secs))
      (apply 'funcall function args)))

As that way it will use `run-with-timer` though only when user is idle
for SECS.

--
Jean Louis