I have a function that gets called when idle, but I would like it to run only when a frame has input focus.

My current work around is to use focus-in-hook and focus-out-hook to change the behavior when idle, but I'd like to simplify it by just having one function that would check whether or not it had focus. Here's the code I am working with:

(use-package zone
  :ensure shut-up
  :commands (zone-when-idle)
  :bind ("C-c z" . zone)
  (setq zone-timeout 30)
  (defun zone-when-idle-and-focused ()
    "Use with `focus-in-hook' to only zone when our focus is back in Emacs."
    (zone-when-idle (or zone-timeout 30)))
  (defun zone-nodoze ()
    "Use with `focus-out-hook' so we don't zone when our focus is elsewhere."
    (let ((inhibit-message t)) (zone-leave-me-alone)))
  (add-hook 'focus-in-hook #'zone-when-idle-and-focused)
  (add-hook 'focus-out-hook #'zone-nodoze)
  (zone-when-idle zone-timeout))
  • Does the function selected-frame help any?
    – lawlist
    Jul 14 '16 at 5:38
  • selected-frame doesn't seem to help; it reports the same frame whether or not the frame has input focus when the idle-timer function runs.
    – aculich
    Jul 14 '16 at 5:52
  • The following Emacs discussion on the mailing list (initiated by Marcin Borkowski) deals with this issue. Perhaps there is something in there that will answer your question -- How to determine (from Elisp) whether the Emacs frame has focus?: lists.gnu.org/archive/html/help-gnu-emacs/2015-11/msg00160.html
    – lawlist
    Jul 14 '16 at 6:22
  • What Marcin asks in the thread sounds like exactly what I am looking for, but I couldn't find an answer that worked and, it seems, neither did he in that discussion.
    – aculich
    Jul 14 '16 at 14:17
  • 1
    Note that you can't know whether a terminal frame has input focus. Jul 14 '16 at 18:41

Old question but if anyone else has the same problem (frame-focus-state) is available in Emacs 27.1 (and possibly before).

From the manual:

(frame-focus-state &optional FRAME)

Return FRAME’s last known focus state.
If nil or omitted, FRAME defaults to the selected frame.

Return nil if the frame is definitely known not be focused, t if
the frame is known to be focused, and ‘unknown’ if we don’t know.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.