Here's a Python implementation of what @alanc proposed.
import Xlib
import Xlib.display
disp = Xlib.display.Display()
root = disp.screen().root
NET_ACTIVE_WINDOW = disp.intern_atom('_NET_ACTIVE_WINDOW')
NET_WM_NAME = disp.intern_atom('_NET_WM_NAME')
last_seen = {'xid': None}
def get_active_window():
window_id = root.get_full_property(NET_ACTIVE_WINDOW,
Xlib.X.AnyPropertyType).value[0]
focus_changed = (window_id != last_seen['xid'])
last_seen['xid'] = window_id
return window_id, focus_changed
def get_window_name(window_id):
try:
window_obj = disp.create_resource_object('window', window_id)
window_name = window_obj.get_full_property(NET_WM_NAME, 0).value
except Xlib.error.XError:
window_name = None
return window_name
if __name__ == '__main__':
root.change_attributes(event_mask=Xlib.X.PropertyChangeMask)
while True:
win, changed = get_active_window()
if changed:
print(get_window_name(win))
while True:
event = disp.next_event()
if (event.type == Xlib.X.PropertyNotify and
event.atom == NET_ACTIVE_WINDOW):
break
The more fully-commented version I wrote as an example for someone is in this gist.
XGetInputFocus()
from the event handler to find out who has it when moved would be less overhead. How realtime does this have to be ? If the answer to that is "a sec is fine" then the polling method seems best. – Gemination