- How to simulate key press and mouse movement in Linux
- Installation of Xdotool on Linux
- Basic Usage of Xdotool
- Bonus
- Support Xmodulo
- xvkbd — эмулятор клавиатуры в Ubuntu Linux
- Установка
- Использование
- Эмуляция нажатия мультимедийных клавиш в Windows, Linux и Mac OS X
- Эмуляция нажатия клавиатуры в Windows
- Эмуляция нажатия клавиатуры в Linux
- Эмуляция нажатия клавиатуры в Mac OS X
How to simulate key press and mouse movement in Linux
Have you ever dreamed of your computer doing stuff automatically for you? Probably not if you just watched Terminator. But except for that, scripting and task automation are every power user’s dreams. If a lot of solutions exist today to fit such goal, it is sometimes hard to pick the simple, smart, and efficient one out of the lot. I cannot pretend to have found it myself, but in the mean time, my preference goes to neat software called xdotool . Its approach is intuitive as it stands as an X11 automation tool. In other words, xdotool can simulate key presses and even mouse events from reading a text file.
Installation of Xdotool on Linux
For Ubuntu, Debian or Linux Mint, you can just do:
$ sudo apt-get install xdotool
For Fedora, use yum command:
For CentOS user, the package is available in EPEL repo. After enabling EPEL repo, simply use yum command as above.
For Arch user, the package is available in the Community repo:
If you cannot find xdotool for your distribution, you can always download it from the official website.
Basic Usage of Xdotool
As intuitive as it is, xdotool remains a scripting application. Hence you have to know the syntax in order to use it properly. Rest assured though, the syntax is very simple and quick to pick up, relative to the extent of the program’s features.
First, it is very easy to simulate key press. From the terminal, you can type the command:
$ xdotool key [name of the key]
If you want to chain two keys, use the + operator between them. For example, to switch windows:
To have xdotool type for you, use the type command:
$ xdotool type '[text 1="type" language="to"][/text]'
That’s already enough for basic key pressing. But one of the many strengths of xdotool is its ability to put the focus on a particular window. It can fetch the right window, and then type in it, preventing all your recorded keystrokes to just vaporize in thin air. For this, the simplest command is:
$ xdotool search --name [name of the window] key Linux имитация нажатия клавиши
This will search through the opened window for one with the name matching the search, give it the focus, and then simulate the key pressing.
A bit more advanced, but very useful, xdotool can simulate mouse movement and click. For example:
With the above command, you can place the cursor at coordinates (x,y) of your screen (in pixels). You can also combine it with the click argument:
$ xdotool mousemove x y click 1
This will move the mouse to (x,y), and click with the left button. The 1 represents the left button of the mouse, 2 would be the scroll wheel, 3 the right button, etc.
Finally, once you have your commands in mind, you might want to actually dump it in a file to edit and play. For that, there is more than one syntax. You can write is a bash script:
#!/bin/bash xdotool [command 1] xdotool [command 2] . . .
where you write your commands in a separate file and plug its name as the argument.
Bonus
As a bonus to this post, here is a concrete example of xdotool in action. You may or may not have heard of Bing, the Microsoft’s search engine. In the latter case, you have then never heard of Bing Rewards: a program that allows you to trade Bing points for Amazon’s and other gift cards. To earn those points, you can do up to 30 searches a day on Bing, each search giving you 0.5 point. In other words, you have to make Bing your default search engine, and use it every day.
Or, you can use this xdotool script, which will automatically give focus to Firefox (replace it with your favorite navigator), and perform a search using the fortune command to generate some random words. In about 30 seconds, all your daily searches will be done.
#!/bin/bash for i in do WID=`xdotool search --title "Mozilla Firefox" | head -1` xdotool windowfocus $WID xdotool key ctrl+l xdotool key Tab SENTENCE="$(fortune | cut -d' ' -f1-3 | head -1)" xdotool type $SENTENCE xdotool key "Return" sleep 4 done
To conclude, I really like xdotool even if its full capabilities extend way beyond the scope of this post. It is a really approachable way to scripting and task automation. The downside is that it probably is not the most efficient one. But again, it does the job, and isn’t too much of a bother to learn.
What are your thoughts on xdotool ? Do you prefer another automation tool to it? And why? Let us know in the comments.
Support Xmodulo
This website is made possible by minimal ads and your gracious donation via PayPal or credit card
Please note that this article is published by Xmodulo.com under a Creative Commons Attribution-ShareAlike 3.0 Unported License. If you would like to use the whole or any part of this article, you need to cite this web page at Xmodulo.com as the original source.
xvkbd — эмулятор клавиатуры в Ubuntu Linux
Утилита xvkbd используется для эмуляции нажатия клавиш и клавиатурных сочетаний. Утилита не доступна из PPA репозитория, поэтому вам придется компилировать исходники, а также, скорее всего, потребуется установка дополнительных пакетов. Если вы не привязаны именно к этой тулзе — я бы порекомендовал использовать более функциональный аналог xdotool .
Примечание
Версия 3.0 не умела эмулировать нажатие одиночных мета-клавиш — Meta , Control , Alt , а только в паре с символом. Написав об этом разработчику (T.Sato, VEF00200[собака]nifty.ne.jp), он удивительно быстро отреагировал и выложил новую версию.
Установка
Качаем нужную версию (в данный момент xvkbd 3.3) тут и распаковываем архив в любой каталог, после чего переходим в консоли в этот каталог. Для компиляции нам понадобится утилита xmkmf , устанавливаем:
xmkmf; make install install.man
Для отладки запускайте утилиту xvkbd с опцией -debug .
Внимание!
Ошибка xvkbd.c:35:25: фатальная ошибка: X11/Xaw/Box.h: Нет такого файла или каталога компиляция прервана при установке на Kubuntu 11.10 лечится установкой следующих пакетов:
apt-get install libxaw7-dev xaw3dg-dev libxtst-dev
Использование
xvkbd -xsendevent -text '\[Control_L]a'
Не используйте опцию xsendevent для эмуляции одиночных клавиш-модификаторов!
Эмуляция нажатия мультимедийных клавиш в Windows, Linux и Mac OS X
Платформенно-зависимый код будем отделять директивами #ifdef OS_TYPE и #endif (еще часть кода на Objective-C вынесем в отдельный файл macx.mm, но об этом позже).
Эмуляция нажатия клавиатуры в Windows
В данной операционной системе за отправку сообщений отвечает функция SendInput. Она позволяет отправлять сообщения с кодами, полный перечень которых представлен на странице MSDN Virtual-Key Codes.
Для использования этой функции необходимо подключить заголовочный файл .
#ifdef Q_OS_WIN32 #define WINVER 0x0500 #include #endif
Примеров использования данной функции в интернете много и ее применение не должно вызвать проблем, поэтому сразу привожу код (в части Windows):
sendKeyEventToSystem(Qt::Key qtKey) < //функция эмуляции нажатия клавиши. qtKey - тип клавиши #ifdef Q_OS_WIN32 INPUT ip; //устройство ввода ip.type = INPUT_KEYBOARD; ip.ki.wScan = 0; ip.ki.time = 0; ip.ki.dwExtraInfo = 0; //в зависимости от типа клавиши switch (qtKey) < case Qt::Key_MediaPrevious: ip.ki.wVk = VK_MEDIA_PREV_TRACK; //предыдущий трек break; case Qt::Key_MediaTogglePlayPause: ip.ki.wVk = VK_MEDIA_PLAY_PAUSE; //для переключения режима воспроизведения break; case Qt::Key_MediaNext: ip.ki.wVk = VK_MEDIA_NEXT_TRACK; //следующий трек break; default: return; break; >//посылаем событие нажатия клавиши ip.ki.dwFlags = 0; SendInput(1, &ip, sizeof(INPUT)); //а затем отжатия клавиши ip.ki.dwFlags = KEYEVENTF_KEYUP; SendInput(1, &ip, sizeof(INPUT)); #endif >
Здесь и далее в примерах будут использоваться всего 3 клавиши. В конце статьи приведена таблица соответствия кодов.
Эмуляция нажатия клавиатуры в Linux
Для эмуляции клавиш в Linux, на мой взгляд, проще всего использовать библиотеку разработчиков libXtst (X11 Record extension library).
Для ее получения из пакетов необходимо выполнить команду:
sudo apt-get install libxtst-dev
В начале файла подключим необходимые заголовочные файлы и определим ряд констант, соответствующих кодам мультимедийных клавиш (дело в том, что в файле X11/keysymdef.h коды для мультимедийных клавиш отсутствуют).
#ifdef Q_OS_LINUX #include #include #define XF86AudioLowerVolume 0x1008ff11 #define XF86AudioMute 0x1008ff12 #define XF86AudioRaiseVolume 0x1008ff13 #define XF86AudioPlay 0x1008ff14 #define XF86AudioStop 0x1008ff15 #define XF86AudioPrev 0x1008ff16 #define XF86AudioNext 0x1008ff17 #define XF86AudioPause 0x1008ff31 #endif
#ifdef Q_OS_LINUX unsigned int key; unsigned int keycode; switch (qtKey) < case Qt::Key_MediaPrevious: key = XF86AudioPrev; break; case Qt::Key_MediaTogglePlayPause: key = XF86AudioPlay; break; case Qt::Key_MediaNext: key = XF86AudioNext; break; default: return; break; >// подключаемся к X Display *display; display = XOpenDisplay(NULL); // получаем код клавиши keycode = XKeysymToKeycode(display, key); // эмулируем нажатие клавиши XTestFakeKeyEvent(display, keycode, 1, 0); // эмулируем отжатие клавиши XTestFakeKeyEvent(display, keycode, 0, 0); // очищаем буфер X XFlush(display); // отключаемся от X XCloseDisplay(display); #endif
Эмуляция нажатия клавиатуры в Mac OS X
Попытки найти решение для MacOS X не приносили плодов (скупые примеры были написаны на Objective-C), до тех пор, пока в гугле не натолкнулся на статью с хабра Интеграция приложений Qt в среду Mac OS X (с использованием Cocoa и Objective-C++). Мне уже ранее попадалась англоязычная статья, в которой описывалось, как изолировать код C++ для использования в Objective-C приложении. Мне же нужно было совершенно противоположное — изолировать Objective-C код (который выполнял нужные мне функции, но в то же время на который ругался компиллятор). Все оказалось достаточно просто:
1. создал файл macx.mm и разместил в нем Objective-С код (при этом в файле проекта автоматически появилась строка
OBJECTIVE_SOURCES += macx.mm
2. создал файл macx.h и разместил в нем объявление функции из macx.mm (добавив #include «macx.h» в macx.mm).
3. в файле проекта добавил подключение необходимых фреймворков, в частности:
macx:LIBS += -framework ApplicationServices -framework IOKit
4. Внутри макроса условной компиляции для Mac OS X добавил необходимые хидеры и macx.h.
5. В уже знакомой вам switch-case структуре вставил вызовы новоиспеченной функции.
Таким образом в начале файла у нас появилась конструкция для Mac OS X:
#ifdef Q_OS_MAC #include //оставил для типа UInt8 #include //коды клавиш #include "mac.h" //определение функции для вызова Objective-C кода #endif
#ifdef Q_OS_MAC switch (qtKey) < case Qt::Key_MediaPrevious: HIDPostAuxKey( NX_KEYTYPE_PREVIOUS ); break; case Qt::Key_MediaTogglePlayPause: HIDPostAuxKey( NX_KEYTYPE_PLAY ); break; case Qt::Key_MediaNext: HIDPostAuxKey( NX_KEYTYPE_NEXT ); break; default: return; break; >#endif
#import #import #import #include "macx.h" static io_connect_t get_event_driver(void) < static mach_port_t sEventDrvrRef = 0; mach_port_t masterPort, service, iter; kern_return_t kr; if (!sEventDrvrRef) < // Get master device port kr = IOMasterPort( bootstrap_port, &masterPort ); check( KERN_SUCCESS == kr); kr = IOServiceGetMatchingServices( masterPort, IOServiceMatching( kIOHIDSystemClass ), &iter ); check( KERN_SUCCESS == kr); service = IOIteratorNext( iter ); check( service ); kr = IOServiceOpen( service, mach_task_self(), kIOHIDParamConnectType, &sEventDrvrRef ); check( KERN_SUCCESS == kr ); IOObjectRelease( service ); IOObjectRelease( iter ); >return sEventDrvrRef; > void HIDPostAuxKey(const UInt8 auxKeyCode ) < NXEventData event; kern_return_t kr; IOGPoint loc = < 0, 0 >; // Сообщение о нажатии клавиши UInt32 evtInfo = auxKeyCodeЗаключение:
Для меня было немного странно, что до сих пор не существует открыто доступной кроссплатформенной библиотеки, позволяющей выполнять отправку сообщений (в том числе события клавиатуры, мыши и д.р.). Во всяком случае мне такую библиотеку так и не получилось найти. Представленный код далек от совершенства (представляю, как разрастется switch-case последовательность при добавлении новых клавиш). Но тем не менее пусть это будет небольшой вклад в общую копилку базы знаний о написании кросплатформенных приложений.
В ходе работы над статьей было замечено, что VirtualBox перехватывает нажатия мультимедийных клавиш (проверялось на Ubuntu — c «железа» все работало). Данного недостатка лишена WMWare (проверялось на Mac OS X).Приложение: Перечень мультимедийных клавиш и их определений (с помощью #define).
Qt::Key | Windows | Linux | Mac OS X |
---|---|---|---|
Qt::Key_VolumeDown | VK_VOLUME_DOWN | XF86AudioLowerVolume | NX_KEYTYPE_SOUND_DOWN |
Qt::Key_VolumeMute | VK_VOLUME_MUTE | XF86AudioMute | NX_KEYTYPE_MUTE |
Qt::Key_VolumeUp | VK_VOLUME_UP | XF86AudioRaiseVolume | NX_KEYTYPE_SOUND_UP |
Qt::Key_BassBoost | |||
Qt::Key_BassUp | |||
Qt::Key_BassDown | |||
Qt::Key_TrebleUp | |||
Qt::Key_TrebleDown | |||
Qt::Key_MediaPlay | VK_MEDIA_PLAY_PAUSE | XF86AudioPlay | NX_KEYTYPE_PLAY |
Qt::Key_MediaStop | VK_MEDIA_STOP | XF86AudioStop | |
Qt::Key_MediaPrevious | VK_MEDIA_PREV_TRACK | XF86AudioPrev | NX_KEYTYPE_PREVIOUS |
Qt::Key_MediaNext | VK_MEDIA_NEXT_TRACK | XF86AudioNext | NX_KEYTYPE_NEXT |
Qt::Key_MediaRecord | |||
Qt::Key_MediaPause | XF86AudioPause | ||
Qt::Key_MediaTogglePlayPause | VK_MEDIA_PLAY_PAUSE | XF86AudioPlay | NX_KEYTYPE_PLAY |
Ссылки по теме:
1. Существующие подходы к решению проблемы: C++ (Qt) cross-platform library for simulating keyboard input, sendkeys, send kestrokes, etc
2. Описание функции SendInput и перечень кодов клавиатуры на сайте MSDN.
3. Simulating Mediakey Presses in C & X11 — в статье описывается, как в Linux с помощью утилиты «xev» (в Ubuntu: «sudo apt-get install x11-utils») можно узнать коды клавиш, а также в дополнение статья с archlinux.org.
4. Эмуляция мультимедийных клавиш в MacOS X на языке программирования Python.