I also included the code I wrote in "screenshots using Python under Linux" for finding a particular window id from its name.
As an example the following code takes a window name as an argument to the program when run, finds the window id and then sends the key press of F11 (the window I wanted to interact with was a browser window and therefore it will go fullscreen).
#!/usr/bin/python
"""
Issue a keypress event in X to a specific window
"""
from Xlib import XK, display, ext, X, protocol
import sys
import time
def get_window(display, name):
root_win = display.screen().root
window_list = [root_win]
while len(window_list) != 0:
win = window_list.pop(0)
if win.get_wm_name() == name:
return win.id
children = win.query_tree().children
if children != None:
window_list += children
print 'Unable to find window matching - %s\n' % name
sys.exit(1)
d=display.Display()
win=get_window(d,sys.argv[1])
keysym=XK.string_to_keysym("F11")
keycode=d.keysym_to_keycode(keysym)
event = protocol.event.KeyPress(
time = int(time.time()),
root = d.screen().root,
window = win,
same_screen = 0, child = X.NONE,
root_x = 0, root_y = 0, event_x = 0, event_y = 0,
state = 0,
detail = keycode
)
d.send_event(win, event, propagate=True)
d.sync()
event = protocol.event.KeyRelease(
time = int(time.time()),
root = d.screen().root,
window = win,
same_screen = 0, child = X.NONE,
root_x = 0, root_y = 0, event_x = 0, event_y = 0,
state = 0,
detail = keycode
)
d.send_event(win, event, propagate=True)
d.sync()
"""
Issue a keypress event in X to a specific window
"""
from Xlib import XK, display, ext, X, protocol
import sys
import time
def get_window(display, name):
root_win = display.screen().root
window_list = [root_win]
while len(window_list) != 0:
win = window_list.pop(0)
if win.get_wm_name() == name:
return win.id
children = win.query_tree().children
if children != None:
window_list += children
print 'Unable to find window matching - %s\n' % name
sys.exit(1)
d=display.Display()
win=get_window(d,sys.argv[1])
keysym=XK.string_to_keysym("F11")
keycode=d.keysym_to_keycode(keysym)
event = protocol.event.KeyPress(
time = int(time.time()),
root = d.screen().root,
window = win,
same_screen = 0, child = X.NONE,
root_x = 0, root_y = 0, event_x = 0, event_y = 0,
state = 0,
detail = keycode
)
d.send_event(win, event, propagate=True)
d.sync()
event = protocol.event.KeyRelease(
time = int(time.time()),
root = d.screen().root,
window = win,
same_screen = 0, child = X.NONE,
root_x = 0, root_y = 0, event_x = 0, event_y = 0,
state = 0,
detail = keycode
)
d.send_event(win, event, propagate=True)
d.sync()
While this seemed to work (my Firefox browser window went into fullscreen mode), I did start to see some strange behaviour, such as none of the menus would display either from the toolbar or right clicking in the window. I did notice that clicking on a menu did very briefly flash up what looked like an outline, so I wondered if this could have anything to do with focus and modified my code like so.
#!/usr/bin/python
"""
Issue a keypress event in X to a specific window
"""
from Xlib import XK, display, ext, X, protocol
import sys
import time
def get_window(display, name):
root_win = display.screen().root
window_list = [root_win]
while len(window_list) != 0:
win = window_list.pop(0)
#print win.get_wm_name()
if win.get_wm_name() == name:
return win.id
children = win.query_tree().children
if children != None:
window_list += children
print 'Unable to find window matching - %s\n' % name
sys.exit(1)
d=display.Display()
win=get_window(d,sys.argv[1])
keysym=XK.string_to_keysym("F11")
keycode=d.keysym_to_keycode(keysym)
#store current input focus
currentfocus=d.get_input_focus()
#set input focus to selected window
d.set_input_focus(win, X.RevertToParent,X.CurrentTime)
#send keypress and keyrelease
ext.xtest.fake_input(d, X.KeyPress, keycode)
ext.xtest.fake_input(d, X.KeyRelease, keycode)
#revert focus to original window
d.set_input_focus(currentfocus.focus,X.RevertToParent,X.CurrentTime)
d.sync()
d.close()
"""
Issue a keypress event in X to a specific window
"""
from Xlib import XK, display, ext, X, protocol
import sys
import time
def get_window(display, name):
root_win = display.screen().root
window_list = [root_win]
while len(window_list) != 0:
win = window_list.pop(0)
#print win.get_wm_name()
if win.get_wm_name() == name:
return win.id
children = win.query_tree().children
if children != None:
window_list += children
print 'Unable to find window matching - %s\n' % name
sys.exit(1)
d=display.Display()
win=get_window(d,sys.argv[1])
keysym=XK.string_to_keysym("F11")
keycode=d.keysym_to_keycode(keysym)
#store current input focus
currentfocus=d.get_input_focus()
#set input focus to selected window
d.set_input_focus(win, X.RevertToParent,X.CurrentTime)
#send keypress and keyrelease
ext.xtest.fake_input(d, X.KeyPress, keycode)
ext.xtest.fake_input(d, X.KeyRelease, keycode)
#revert focus to original window
d.set_input_focus(currentfocus.focus,X.RevertToParent,X.CurrentTime)
d.sync()
d.close()
This seems to work much better and Firefox still works correctly.