I am faced with a specific problem: My elisp code, that reacts to DBus events, needs to know whether Emacs window it is currently running in has focus or not at the moment the event arrived.
When running under X, the answer is known, and I'll put it there in case anyone stumbles on this question:
(defun x-active-window ()
"Return the window ID of the current active window in X \
as given by the _NET_ACTIVE_WINDOW of the root window set by the \
window-manager, or nil if not able to."
(and (eq (window-system) 'x)
(x-window-property
"_NET_ACTIVE_WINDOW" nil "WINDOW" 0 nil t)))
(defun frame-outer-window-id (frame)
"Return the frame outer-window-id property, or nil if FRAME not \
of the correct type."
(and (framep frame)
(string-to-number (frame-parameter frame 'outer-window-id))))
(defun x-active-window-p (frame)
"Check if FRAME is the X active window. \
Return t if frame has focus or nil otherwise."
(and (framep frame)
(eq (frame-outer-window-id frame)
(x-active-window))))
(x-active-window-p (selected-frame)))
Unfortunately, I am also running the current master
emacs with pgtk on Wayland, where the above doesn't work at all, because there's no XWayland underneath. After much mucking around, I've been able to come up with this horror:
(defun pgtk-active-window ()
"Returns _updateTitleID of the active window in Gnome Shell."
(second (dbus-call-method
:session
"org.gnome.Shell"
"/org/gnome/Shell"
"org.gnome.Shell"
"Eval"
"global.display.focus_window._updateTitleID;")))
I.e. through poorly documented, roundabout methods (by calling into Gnome Shell over DBus and telling it to execute a line of javascript) we get one, apparently unique parameter about the window currently in focus, (that's the only one it returns) which does not appear to change during window lifecycle. Then we can compare it to the one we stored during startup, when our window was in focus.
It works, for suitably small quantities of "works", but all the problems with this approach should be obvious. However, I was not able to find any other way a frame could determine if it is currently in focus in in PGTK, and going through the emacs source did not enlighten me either.
Does a better way currently exist?