60

I'm using a Raspberry Pi in combination with Chromium (kiosk mode) to show up some stats. The Pi doesn't have a connected keyboard so I searched for a solution to send keystrokes from the terminal to the Chromium (tab) process. Normal input does work but how do I send something like F5 (a special key: browser refresh) via this solution?

# pidof chromium
20809 20790 20788 20786 20783
# echo 'some text' > /proc/20809/fd/0
1

6 Answers 6

77

GUI programs don't read from their standard input, they get their input from the X server. There are tools to inject a keystroke to a window. xdotool is fairly common and convenient.

You'll need to find the window ID that you want to send the keystroke to. You can do that with xdotool. xdotool search --class Chrome returns the list of window IDs of all the Chrome windows. If this returns more than one, you need to pick the one you want. You can use xdotool search --name to match on the title instead of the class. You can also parse the output of wmctrl and extract the desired window ID.

Once you've found the right window ID, you can call xdotool to inject a keystroke. Unfortunately, many applications reject synthetic events, i.e. keystrokes and mouse events sent by another application. This is the case with current versions of Chrome. It's possible to inject a keystroke from another application by a different mechanism, but that requires the window to be focused. You can do all of that with xdotool, but it'll cause the focus to quickly flicker to the Chrome window and back. The following snippet sends F5 to the first Chrome window (in a somewhat arbitrary order).

xdotool search --class Chrome windowactivate --sync %1 key F5 windowactivate $(xdotool getactivewindow)

Or with older versions of xdotool:

xdotool windowactivate $(xdotool search --class Chrome) &&
xdotool key F5 &&
xdotool windowactivate $(xdotool getactivewindow)

Remember that this sends F5 to that window and it's up to the program to decide what to do with it. In Chrome, this reloads the current tab.

9
  • 4
    the --windowid flag is now --window (the command warns you as much) Dec 26, 2015 at 17:31
  • 2
    The --title option is now --name (the command faithfully warns as much)
    – jpaugh
    Jul 16, 2016 at 4:01
  • 3
    the nesting is totally unnecessary, it should be xdotool search --class Chrome key F5
    – phil294
    Mar 3, 2017 at 0:18
  • 1
    @Blauhirn The nesting was necessary in older versions of xdotool. But thanks, I've updated my answer to also show the newer syntax. Mar 3, 2017 at 8:34
  • 1
    Reference table for keycodes - linux.org/threads/xdotool-keyboard.10528
    – M.Viking
    Oct 3, 2022 at 17:11
18

The solution suggested above used xdotool like this

 xdotool key --windowid <window> <keystroke>

which didn't work for me. After some experimenting, I arrived at

 xdotool windowactivate --sync <window> key <keystroke>

Once, that seemed to be working, I defined some scripts and updated my .lircrc file as show here:

http://pcfellow.com/ClementineRemote.html

2
  • I wonder why your first example doesn't work? It would be nice to send keystrokes to non-focused windows.
    – Geremia
    Feb 25, 2017 at 23:40
  • 2
    @Geremia, it probably does not work for the reason provided in the SENDEVENT NOTES in the xdotool documentation.
    – Janthelme
    Dec 8, 2018 at 4:41
6

I had a similar use case on a Raspberry Pi running Raspbian Wheezy. I needed to rotate tabs on Chrome using kiosk mode (sadly, installing an extension to do this on old Chrome is no longer reasonable). The accepted answer's example has some typos or simply doesn't work with my software versions, here is what works for me:

xdotool key --window "$(xdotool search --class Chromium | head -1)" Ctrl+Tab
6

If you're using Chromium to display a custom webpage and you want it to refresh regularly, you can add the following tag to it :

<meta http-equiv="refresh" content="5">

to automatically refresh it every 5 seconds (you can set it shorter or longer if you want).

2
  • 3
    Nice try but i don't own Twitter, the monitoring software of my ISP and other sites I have to monitor ;) I probably should have mentioned this before
    – burnersk
    Aug 23, 2013 at 6:13
  • 8
    You could insert that tag into the page using a user script. Might be a less brittle solution than sending a keypress to the window.
    – sherbang
    Jun 4, 2016 at 8:28
2

I've historically used Auto Hot Key to do things like send key presses, however that's not available on Linux, but a quick Google search reveals that there is IronAHK (http://www.ironahk.net/) there isn't much documentation available yet, but it may do the trick.

1
0

Hello from the future!

I wanted to improve on Gilles 'SO- stop being evil' answer, but being a latecomer I can't even comment (50 rep) and the edit queue is full.

For me this works:

xdotool search --name YouTube key --window %1 alt+shift+r

When I run this command the Firefox window containing the phrase “YouTube” (FireTitle add-on) will get the Alt+Shift+r keys and the current tab (Go to random tab add-on).

I have bound a KDE global shortcut to an UHK key, if you're further curious.

Now I've seen in the comments that supposedly Chrome does not accept synthetic events. This is another reason to give up Chrome if it doesn't allow you to modify your workflow (apart from all that pesky monopolization of the Internets thing).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .