XDOTOOL(1) | XDOTOOL(1) |
xdotool - command-line X11 automation tool
xdotool cmd args...
Notation: Some documentation uses [window] to denote an optional window argument. This case means that the argument, if not present, will default to "%1". See "WINDOW STACK" for what "%1" means.
xdotool lets you programmatically (or manually) simulate keyboard input and mouse activity, move and resize windows, etc. It does this using X11's XTEST extension and other Xlib functions.
There is some support for Extended Window Manager Hints (aka EWMH or NetWM). See the "EXTENDED WINDOW MANAGER HINTS" section for more information.
See also: "SENDEVENT NOTES" and "WINDOW STACK"
Type a given keystroke. Examples being "alt+r", "Control_L+J", "ctrl+alt+n", "BackSpace".
Generally, any valid X Keysym string will work. Multiple keys are separated by '+'. Aliases exist for "alt", "ctrl", "shift", "super", and "meta" which all map to Foo_L, such as Alt_L and Control_L, etc.
In cases where your keyboard doesn't actually have the key you want to type, xdotool will automatically find an unused keycode and use that to type the key.
With respect to "COMMAND CHAINING", this command consumes the remainder of the arguments or until a new xdotool command is seen, because no xdotool commands are valid keystrokes.
Example: Send the keystroke "F2"
xdotool key F2
Example: Send 'a' with an accent over it (not on English
keyboards, but still works with xdotool)
xdotool key Aacute
Example: Send ctrl+l and then BackSpace as separate keystrokes:
xdotool key ctrl+l BackSpace
Example: Send ctrl+c to all windows matching title 'gdb' (See
"COMMAND CHAINING")
xdotool search --name gdb key ctrl+c
Types as if you had typed it. Supports newlines and tabs (ASCII newline and tab). Each keystroke is separated by a delay given by the --delay option.
With respect to "COMMAND CHAINING", this command consumes the remainder of the arguments and types them. That is, no commands can chain after 'type'.
Example: to type 'Hello world!' you would do:
xdotool type 'Hello world!'
You can move the mouse to the previous location if you specify 'restore' instead of an X and Y coordinate. Restoring only works if you have moved previously in this same command invocation. Further, it does not work with the --window option.
For example, to click the top-left corner of the screen and
move the mouse to the original position before you moved it, use this:
xdotool mousemove 0 0 click 1 mousemove restore
"WINDOW STACK" references are valid here, such as %1 and %@. Though, using %@ probably doesn't make sense.
The default is the current screen. If you specify --window, the --screen flag is ignored.
Rotation starts at 'up' (0 degrees) and rotates clockwise: 90 = right, 180 = down, 270 = left.
The origin defaults to the center of the current screen. If you specify a --window, then the origin is the center of that window.
Note: We wait until the mouse moves at all, not necessarily that it actually reaches your intended destination. Some applications lock the mouse cursor to certain regions of the screen, so waiting for any movement is better in the general case than waiting for a specific target.
Rotation starts at 'up' (0 degrees) and rotates clockwise: 90 = right, 180 = down, 270 = left.
Note that we wait until the mouse moves at all, not necessarily that it actually reaches your intended destination. Some applications lock the mouse cursor to certain regions of the screen, so waiting for any movement is better in the general case than waiting for a specific target.
Buttons generally map this way: Left mouse is 1, middle is 2, right is 3, wheel up is 4, wheel down is 5.
The default, if no window is given, depends on the window stack. If the window stack is empty the current window is typed at using XTEST. Otherwise, the default is "%1" (see "WINDOW STACK").
% xdotool getmouselocation --shell X=880 Y=443 SCREEN=0 WINDOW=16777250 % eval $(xdotool getmouselocation --shell) % echo $X,$Y 714,324
Options are:
Event timeline
* Mouse hits an edge or corner. * If delay is nonzero, the mouse must stay in this edge or corner until delay time expires. * If still in the edge/corner, trigger. * If quiesce is nonzero, then there is a cool-down period where the next trigger cannot occur
Valid 'where' values are:
Examples:
# Activate google-chrome when you move the mouse to the bottom-left corner:
xdotool behave_screen_edge bottom-left \
search --class google-chrome windowactivate
# Go to the next workspace (right). Known to work in GNOME (metacity and compiz) xdotool behave_screen_edge --delay 500 bottom-right key XF86Forward # Activate firefox and do a web search in a new tab for text in your clipboard xdotool behave_screen_edge --delay 1000 top-left \ search --classname Navigator \ windowactivate --sync key --delay 250 ctrl+t ctrl+k ctrl+v Return
The result is saved to the window stack for future chained commands. See "WINDOW STACK" and "COMMAND CHAINING" for details.
The default options are "--name --class --classname" (unless you specify one one or more of --name --class or --classname).
The options available are:
The default is no search limit (which is equivalent to '--limit 0')
xdotool search --all --pid 1424 --name "Hello World"
This will match only windows that have "Hello World" as a name and are owned by pid 1424.
xdotool search --any --pid 1424 --name "Hello World"
This will match any windows owned by pid 1424 or windows with name "Hello World"
google-chrome & xdotool search --sync --onlyvisible --class "google-chrome"
xdotool selectwindow windowkill
The command run as a result of the behavior is run with %1 being the window that was acted upon. Examples follow after the event list.
The following are valid events:
Examples:
# Print the cursor location whenever the mouse enters a currently-visible # window: xdotool search --onlyvisible . behave %@ mouse-enter getmouselocation # Print the window title and pid whenever an xterm gets focus xdotool search --class xterm behave %@ focus getwindowname getwindowpid # Emulate focus-follows-mouse xdotool search . behave %@ mouse-enter windowfocus
If no window is given, the default is '%1'. If no windows are on the stack, then this is an error. See "WINDOW STACK" for more details.
Example: Find the PID for all xterms:
xdotool search --class xterm getwindowpid %@
If no window is given, the default is '%1'. If no windows are on the stack, then this is an error. See "WINDOW STACK" for more details.
If the current window has no WM_CLASS property, we assume it is not a normal top-level window and traverse up the parents until we find a window with a WM_CLASS set and return that window id.
If you really want the window currently having focus and don't care if it has a WM_CLASS setting, then use 'getwindowfocus -f'
Percentages are valid for width and height. They are relative to the geometry of the screen the window is on. For example, to make a window the full width of the screen, but half height:
xdotool windowsize I<window> 100% 50%
Percentages are valid with --usehints and still mean pixel-width relative to the screen size.
The options available are:
Note: Because many window managers may ignore or alter the original resize request, we will wait until the size changes from its original size, not necessary to the requested size.
Example: To set a terminal to be 80x24 characters, you would use:
xdotool windowsize --usehints some_windowid 80 24
If the given x coordinate is literally 'x', then the window's current x position will be unchanged. The same applies for 'y'.
Examples:
xdotool getactivewindow windowmove 100 100 # Moves to 100,100 xdotool getactivewindow windowmove x 100 # Moves to x,100 xdotool getactivewindow windowmove 100 y # Moves to 100,y xdotool getactivewindow windowmove 100 y # Moves to 100,y
Percentages are valid for width and height. They are relative to the geometry of the screen the window is on. For example, to make a window the full width of the screen, but half height:
xdotool windowmove I<window> 100% 50%
Uses XSetInputFocus which may be ignored by some window managers or programs.
Options:
If you change this value, your window manager may not notice the change until the window is mapped again, so you may want to issue 'windowunmap' and 'windowmap' to make the window manager take note.
These commands follow the EWMH standard. See the section "EXTENDED WINDOW MANAGER HINTS" for more information.
If no window is given, %1 is the default. See "WINDOW STACK" and "COMMAND CHAINING" for more details.
Viewports are sometimes used instead of 'virtual desktops' on some window managers. A viewport is simply a view on a very large desktop area.
For example, if your screen is 1280x800, you can move to the
2nd workspace by doing:
xdotool set_desktop_viewport 1280 0
Options:
Examples:
# Lock the screen when the mouse sits in the top-right corner
xdotool behave_screen_edge --delay 1000 top-right \
exec gnome-screensaver-command --lock
# Substitute 'xscreensaver-command -lock' if you use that program.
# The following will fail to move the mouse because we use '--sync' and # /bin/false exits nonzero: xdotool exec --sync /bin/false mousemove 0 0 # This succeeds, though, since we do not use --sync on the exec command. xdotool exec /bin/false mousemove 0 0
xdotool can read a list of commands via stdin or a file if you want. A script will fail when any command fails.
Truthfully, 'script' mode isn't fully fleshed out and may fall below your expectations. If you have suggestions, please email the list or file a bug (See CONTACT).
Scripts can use positional arguments (Represented by $1, $2, ...) and environment variables (like $HOME or $WINDOWID). Quoting arguments should work as expected.
Scripts are processed for parameter and environment variable expansion and then run as if you had invoked xdotool with the entire script on one line (using COMMAND CHAINING).
xdotool filename
xdotool -
xdotool - < myfile
You can also write scripts that only execute xdotool. Example:
#!/usr/local/bin/xdotool search --onlyvisible --classname $1 windowsize %@ $2 $3 windowraise %@ windowmove %1 0 0 windowmove %2 $2 0 windowmove %3 0 $3 windowmove %4 $2 $3
This script will take all windows matched by the classname query given by arg1 ($1) and sizes/moves them into a 2x2 grid with windows sized by the 2nd and 3rd parameters.
Here's an example usage:
% ./myscript xterm 600 400
Running it like this will take 4 visible xterms, raise them, and move them into a 2x2 tile grid with each window 600x400 pixels in size.
Any command taking the --clearmodifiers flag will attempt to clear any active input modifiers during the command and restore them afterwards.
For example, if you were to run this command:
xdotool key a
The result would be 'a' or 'A' depending on whether or not you were holding the shift key on your keyboard. Often it is undesirable to have any modifiers active, so you can tell xdotool to clear any active modifiers.
The order of operations if you hold shift while running 'xdotool key --clearmodifiers a' is this:
The --clearmodifiers flag can currently clear of the following:
If you are trying to send key input to a specific window, and it does not appear to be working, then it's likely your application is ignoring the events xdotool is generating. This is fairly common.
Sending keystrokes to a specific window uses a different API than simply typing to the active window. If you specify 'xdotool type --window 12345 hello' xdotool will generate key events and send them directly to window 12345. However, X11 servers will set a special flag on all events generated in this way (see XEvent.xany.send_event in X11's manual). Many programs observe this flag and reject these events.
It is important to note that for key and mouse events, we only use XSendEvent when a specific window is targeted. Otherwise, we use XTEST.
Some programs can be configured to accept events even if they are generated by xdotool. Seek the documentation of your application for help.
Specific application notes (from the author's testing): * Firefox 3 seems to ignore all input when it does not have focus. * xterm can be configured while running with ctrl+leftclick, 'Allow SendEvents' * gnome-terminal appears to accept generated input by default.
Certain commands (search, getactivewindow, getwindowfocus) will find windows for you. These results generally printed to stdout, but they are also saved to memory for future use during the lifetime of the xdotool process. See "COMMAND CHAINING" for more information.
The only modifications support for the window stack are to replace it. That is, two of two sequential searches, only the last one's results will be the window stack.
xdotool supports running multiple commands on a single invocation. Generally, you'll start with a search command (see "WINDOW STACK") and then perform a set of actions on those results.
To query the window stack, you can use special notation "%N" where N is a number or the '@' symbol. If %N is given, the Nth window will be selected from the window stack. Generally you will only want the first window or all windows. Note that the order of windows in the window stack corresponds to the window stacking order, i.e. the bottom-most window will be reported first (see XQueryTree(3)). Thus the order of the windows in the window stack may not be consistent across invocations.
The notation described above is used as the "window" argument for any given command.
For example, to resize all xterms to 80x24:
xdotool search --class xterm -- windowsize --usehints %@ 80 24
Resize move the current window:
xdotool getactivewindow windowmove 0 0
In all cases, the default window argument, if omitted, will default to "%1". It is obviously an error if you omit the window argument and the window stack is empty. If you try to use the window stack and it is empty, it is also an error.
To activate the first firefox window found:
xdotool search --class firefox windowactivate
These would error:
xdotool windowactivate xdotool windowactivate %1 xdotool windowactivate %@
When xdotool exits, the current window stack is lost.
Additionally, commands that modify the "WINDOW STACK" will not print the results if they are not the last command. For example:
# Output the active window: % xdotool getactivewindow 20971533 # Output the pid of the active window, but not the active window id: % xdotool getactivewindow getwindowpid 4686
The following pieces of the EWMH standard are supported:
xdotool (and libxdo) will try to function under all circumstances. However, there may be some cases where functionality is not provided by your X server or by your window manager. In these cases, xdotool will try to detect and tell you if an action requires a feature not currently supported by your system.
For window-manager specific features, see "EXTENDED WINDOW MANAGER HINTS".
In most cases, XTEST is a feature you can enable on your X server if it is not enabled by default.
You can see the list of supported X extensions by typing 'xdpyinfo' and looking the text 'number of extensions: ...'
Typing unusual symbols under non-us keybindings is known to occasionally send the wrong character.
Project site: <http://www.semicomplete.com/projects/xdotool>
Source code and Issues: <https://github.com/jordansissel/xdotool>
EWMH specification: <http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html>
Please send questions to xdotool-users@googlegroups.com. File bugs and feature requests at the following URL:
<https://github.com/jordansissel/xdotool/issues>
Alternately, if you prefer email, feel free to file bugs by emailing the list. What works for you :)
xdotool was written by Jordan Sissel.
This manual page was written originally by Daniel Kahn Gillmor <dkg@fifthhorseman.net> for the Debian project (but may be used by others). It is maintained by Jordan Sissel.
Patches, ideas, and other contributions by many, nice folks. See the CHANGELIST file for who provided what.
2022-04-20 |