# xdotool: X11 automation from the command line

> xdotool fakes keyboard and mouse input and manages windows on X11 through the XTEST extension. It is a small C tool with a large command surface, and it does not work correctly on Wayland.

**jordansissel/xdotool** — fake keyboard/mouse input, window management, and more 

- Repository: https://github.com/jordansissel/xdotool
- Stars: 3,851 · Forks: 346
- Language: C
- License: BSD-3-Clause
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/jordansissel-xdotool

## What xdotool does that a shell script cannot

A shell script can start programs and edit files. It cannot press ctrl+l in a window that is already open, and it cannot resize every visible terminal at once. xdotool fills that gap: the README describes it as a tool that simulates keyboard input and mouse activity, moves and resizes windows, and modifies window properties such as the title. It does this using X11's XTEST extension and other Xlib functions. The audience is anyone who automates a desktop session rather than a server: test harnesses that need synthetic clicks, window-manager scripts, kiosk setups, and people who want a hotkey to rearrange their workspace. The same repository also ships libxdo, a C library for doing the same, so the command line tool and the library share one implementation. The documentation for the commands lives in xdotool.pod, not in the README, which is worth knowing before you go looking for a flag list.

## How the XTEST path works, and where it stops

The mechanism is not a virtual input device. xdotool asks the X server to inject events through XTEST, and uses Xlib calls for window operations such as search, move, resize, activate and close. That distinction matters when you compare it to tools built on Linux's uinput system. Because the events go through the X server, they land in whatever window currently has focus, which is why the README's Firefox example chains search, windowactivate --sync and then key --clearmodifiers ctrl+l: it raises the window, waits for the activation to settle, clears any modifier keys you are physically holding, and only then sends the chord. Each of the cmd_*.c files in the repository root maps to one subcommand, so the surface is a flat set of verbs rather than a scripting language. The limits follow from the same design. Wayland has only partial X11 compatibility, and the README is blunt: typing, window searching and many other functions do not work, and it is unclear if they could ever work. Under XWayland you may reach X11 clients, but that is not the same as controlling the session.

## Installing xdotool from your distribution's packages

The README points at distribution packaging first, and the commands are one line each. On Debian and Ubuntu the package is xdotool:

```bash
apt-get install xdotool
```

Fedora uses dnf, Arch uses pacman, OpenSUSE uses zypper, FreeBSD uses pkg, and macOS has both a Homebrew formula and a MacPorts port:

```bash
dnf install xdotool
pacman -S xdotool
zypper install xdotool
pkg install xdotool
brew install xdotool
```

After that, xdotool type "Hello world" should type into the focused window. If nothing appears, check which window has focus before suspecting the install; the event goes to the focused window, not to your terminal. Building from source is a make away, but it needs the X11 development libraries: xlib, xtst, xi, xkbcommon and xinerama. The Makefile defaults PREFIX to /usr/local and supports DESTDIR for staged installs, which is what packagers use. There is also make showman to generate the manpage that make install will place on the system.

## A first real use: focusing a window and sending a chord

The README's own example is the shortest complete workflow, and it is worth reading as a sequence rather than a single command:

```bash
xdotool search "Mozilla Firefox" windowactivate --sync key --clearmodifiers ctrl+l
```

search finds windows whose name matches the string. windowactivate --sync raises and focuses the match and waits for the X server to confirm before returning. key --clearmodifiers releases any modifiers you are holding so the injected ctrl+l is not polluted by a stuck shift or alt. The second README example shows the batch form, where %@ stands for the set of windows found by the search:

```bash
xdotool search --onlyvisible --classname "gnome-terminal" windowsize %@ 500 500
```

Here --onlyvisible filters out unmapped windows and --classname matches the window class rather than the title, which is more stable across title changes. Two smaller commands round out the basics: xdotool key ctrl+l sends a hotkey, and xdotool selectwindow windowclose closes the first window you click on. That last one is a useful smoke test, because it tells you immediately whether xdotool can see your windows at all.

## The Wayland boundary is the real adoption decision

The README carries a warning rather than a caveat: on Wayland this software will not work correctly. Typing, window searching and many other functions are named as broken, and the project says it is unclear whether they could ever work. This is not a bug that a version bump fixes; it follows from XTEST being an X11 mechanism and from Wayland's design giving clients no way to inject input into other clients. So the first question for any team is not which version to pin but which session type the automation will run under. If your CI runs headless Xvfb, you are on X11 and fine. If your users are on a modern GNOME or KDE Wayland session, xdotool is the wrong tool regardless of how well the command syntax fits your script. The README itself points elsewhere in that case, naming ydotool and dotool, both of which send mouse and keyboard events through Linux's uinput system.

## xdotool versus ydotool: different layers, different failures

The README names ydotool as a Wayland-friendly option, and the difference is architectural rather than cosmetic. ydotool writes to uinput, the kernel's input subsystem, so events enter below the display server and reach Wayland and X11 alike. That is why it keeps working where xdotool does not. The cost is that uinput events are synthetic at the kernel level and depend on the compositor's keymap handling, and ydotool has no equivalent of xdotool's window verbs: search, windowactivate, windowsize and windowclose have no counterpart, because window management is an X11 concept here. xdotool, by contrast, is both an input injector and a window manager client, which is why a single command can raise Firefox and then type into it. If your problem is only sending keystrokes on Wayland, ydotool is the closer fit. If your problem is finding, moving and resizing X11 windows, xdotool is doing work that ydotool does not attempt. wmctrl overlaps with the window-management half of xdotool, but it does not inject input events, so it cannot replace the typing and key examples above.

## Maintenance, packaging and licence cost

The repository is not archived, and the last push was on 2026-09-20. Releases are tagged with a date-shaped version: v4.20260303.1 in March 2026 and v4.20251130.1 in November 2025, with the previous tag v3.20211022.1 from October 2021 carrying a packaging fix for make create-package-deb. That gap is the honest picture of the upgrade cost. The command surface is stable enough that scripts written years ago still run, and the release cadence is driven by packaging and build fixes rather than feature churn, so upgrading is rarely urgent and rarely disruptive. Building from source is where the cost sits: the Makefile needs xlib, xtst, xi, xkbcommon and xinerama development packages, and the default PREFIX is /usr/local, so a source install lands outside your package manager's tracking. The licence is BSD-3-Clause, which is permissive and places few obligations on redistribution, but the COPYRIGHT file in the repository root is the text that governs, and anything beyond reading it is a question for your own legal review. The practical packaging note is DESTDIR support, which is what distributions use to stage installs.

## Conclusion

Adopt xdotool when your session is X11 and you need scripted input or window control from a shell: the packaging is one command on Debian, Fedora, Arch, OpenSUSE, FreeBSD and macOS. Do not adopt it on Wayland, where the README states typing, window searching and many other functions do not work, and do not expect it to drive native Wayland clients. Before relying on it, verify two things on your own machine: that the XTEST extension is available to your session, and that the window class names your scripts search for match what the target applications actually report.

## FAQ

### What is xdotool?

It is an X11 automation tool that simulates keyboard input and mouse activity and can move, resize, hide and modify windows, using the XTEST extension and other Xlib functions. The same repository ships libxdo, a C library that does the same work.

### How do I install xdotool on Linux?

The README lists distribution packages: apt-get install xdotool on Debian and Ubuntu, dnf install xdotool on Fedora, pacman -S xdotool on Arch Linux, and zypper install xdotool on OpenSUSE. FreeBSD and macOS have packages too, via pkg and brew respectively.

### What is the difference between xdotool and ydotool?

xdotool injects events through X11's XTEST extension and only works correctly on X11, while ydotool sends mouse and keyboard events using Linux's uinput system, which the README recommends for Wayland users. ydotool does not offer xdotool's window management verbs such as search and windowactivate.

### What does xdotool do?

It simulates keyboard and mouse input, searches for windows and can move, resize, hide and modify window properties such as the title. If the window manager supports it, it can also switch desktops, move windows between desktops and change the number of desktops.

### Is xdotool safe?

The README does not discuss safety. What it does state is that xdotool injects input through X11's XTEST extension and other Xlib functions, so it acts on windows within your own X session and does not work correctly on Wayland.

## Sources

- [Issues](https://github.com/jordansissel/xdotool/issues)
- [jordansissel/xdotool on GitHub](https://github.com/jordansissel/xdotool)
- [License: BSD-3-Clause](https://github.com/jordansissel/xdotool/blob/main/LICENSE)
- [README](https://github.com/jordansissel/xdotool/blob/main/README.md)
- [Releases](https://github.com/jordansissel/xdotool/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jordansissel-xdotool
