Keyboard automate macro

In my early day’s I used to have a G11 Logitech Keyboard where I could assign a macro to a custom button in toggle mode.

Now I use a different keyboard, but I would like to recreate that system.

So I would like to press § to toggle the following script.

# alias §="xdotool_"
bindkey -s '§' xdotool_
xdotool_() {
    #  keyboard input / automat / macro / xbindkeys #! not on wayland but "xte"

    while true; do
        xdotool key 1
        xdotool key 2
        xdotool key 3
        xdotool key 4
        sleep 0.4
    done

    # while true; do
    # bindkey -s '1'
    # bindkey -s '2'
    # bindkey -s '3'
    # bindkey -s '4'
    # sleep 0.4
    # done
}

The problem in this script is that it is not really in toggle mode…
Is there already a tool, are solution for this?

Thanks in advance.

But thats not a script.

This would be a script:

#!/usr/bin/env bash

while true; do
   xdotool key 1
   xdotool key 2
   xdotool key 3
   xdotool key 4
   sleep 0.4
done

And you are right … the thing itself isnt very toggle-y.

Maybe you could explain more what exactly you want to do …
Do you want the script to continuously xdotool #, until you press the key again, or ? …

I see, well I love to have it in my .aliasrc / .zshrc.
Should it be in an external file as a script?

Yes, the plan is to have it run by press § and end by press § again.

The reason is to simplify the key pressing from several Button to One, as a macro.

An example is skill use in games.

I just meant that is what a script is - a file with the shebang header.

putting functions in your bashrc or zshrc is a perfectly fine way to … add some functions, if thats where you would prefer it to be.

It also appears you are using the same method for assigning the key as well.

But … it would probably be easier to do this toggle thing if it were a standalone script because then it could check against itself running with the script being the process.

Maybe something like this works for you:

~/.local/bin/magickeys.sh

#!/usr/bin/env bash

while true; do
   xdotool key 1
   xdotool key 2
   xdotool key 3
   xdotool key 4
   sleep 0.4
done

Then in your zshrc you could put

xdotool_() {
   pkill magickeys.sh || magickeys.sh
}

Which means kill the process named magickeys.sh, or else start it.


Another way is to build it into the script, like so:

#!/usr/bin/env bash

PIDS=`pidof -o $$ -x magickeys.sh`

if [ x$PIDS != x ]
   then kill -s SIGTERM $PIDS
   else while true; do
      xdotool key 1
      xdotool key 2
      xdotool key 3
      xdotool key 4
      sleep 0.4
   done
fi

Then just assign the key to the script and the script will send a kill signal if running, or start the (xdotool) actions if not.

Thanks so far, I did set up does file as you said, but I could never get the termination of the while loop to work.
The only way to cancel was with CTRL + c

Also, I realize running it from the .zshrc file always needs the terminal.

So I got rid of run it from there, and made a second file call magickeys_off.sh

~/.local/bin/magickeys_off.sh
#!/usr/bin/env bash

# if command -v magickeys >/dev/null 2>&1; then
# if [[ pgrep -x xdotool ]]; then
# if [[ pgrep -x magickeys ]]; then

pkill magickeys.sh || magickeys.sh

# fi

In magickeys_off.sh I try different if else statement to trigger the termination of the while loop, but none of does version works.

I remap the key § in the keyboard setting to ~/.local/bin/magickeys_off.sh

~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml
<?xml version="1.0" encoding="UTF-8"?>

<channel name="xfce4-keyboard-shortcuts" version="1.0">
  <property name="commands" type="empty">
    <property name="default" type="empty">
      <property name="&lt;Alt&gt;F1" type="empty"/>
      <property name="&lt;Alt&gt;F2" type="empty">
        <property name="startup-notify" type="empty"/>
      </property>
      <property name="&lt;Alt&gt;F3" type="empty">
        <property name="startup-notify" type="empty"/>
      </property>
      <property name="&lt;Primary&gt;&lt;Alt&gt;Delete" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;l" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;t" type="empty"/>
      <property name="XF86Display" type="empty"/>
      <property name="&lt;Super&gt;p" type="empty"/>
      <property name="&lt;Primary&gt;Escape" type="empty"/>
      <property name="XF86WWW" type="empty"/>
      <property name="HomePage" type="empty"/>
      <property name="XF86Mail" type="empty"/>
      <property name="Print" type="empty"/>
      <property name="&lt;Alt&gt;Print" type="empty"/>
      <property name="&lt;Shift&gt;Print" type="empty"/>
      <property name="&lt;Super&gt;e" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;f" type="string" value="nemo"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;Escape" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Shift&gt;Escape" type="empty"/>
      <property name="&lt;Super&gt;r" type="empty">
        <property name="startup-notify" type="empty"/>
      </property>
      <property name="&lt;Alt&gt;&lt;Super&gt;s" type="empty"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Delete" type="empty"/>
      <property name="&lt;Control&gt;Escape" type="empty"/>
    </property>
    <property name="custom" type="empty">
      <property name="&lt;Alt&gt;F2" type="string" value="xfce4-appfinder --collapsed">
        <property name="startup-notify" type="bool" value="true"/>
      </property>
      <property name="&lt;Super&gt;r" type="string" value="xfce4-appfinder -c">
        <property name="startup-notify" type="bool" value="true"/>
      </property>
      <property name="XF86WWW" type="string" value="exo-open --launch WebBrowser"/>
      <property name="&lt;Alt&gt;F3" type="string" value="xfce4-appfinder">
        <property name="startup-notify" type="bool" value="true"/>
      </property>
      <property name="&lt;Primary&gt;Escape" type="string" value="xfdesktop --menu"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;Delete" type="string" value="xfce4-session-logout"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;l" type="string" value="xflock4"/>
      <property name="&lt;Super&gt;p" type="string" value="xfce4-display-settings --minimal"/>
      <property name="&lt;Primary&gt;&lt;Shift&gt;Escape" type="string" value="xfce4-taskmanager"/>
      <property name="HomePage" type="string" value="exo-open --launch WebBrowser"/>
      <property name="XF86Display" type="string" value="xfce4-display-settings --minimal"/>
      <property name="override" type="bool" value="true"/>
      <property name="&lt;Primary&gt;Print" type="string" value="xfce4-screenshooter -r"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;c" type="string" value="catfish"/>
      <property name="&lt;Alt&gt;o" type="string" value="deluge-gtk %U"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;z" type="string" value="exo-open --launch TerminalEmulator --drop-down --hide-menubar --hide-toolbar --hide-borders --geometry 77x11"/>
      <property name="&lt;Alt&gt;b" type="string" value="exo-open --launch WebBrowser"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;e" type="string" value="/opt/vscodium-bin/bin/codium --no-sandbox --unity-launch"/>
      <property name="&lt;Alt&gt;p" type="string" value="popcorntime"/>
      <property name="Print" type="string" value="flameshot gui"/>
      <property name="&lt;Alt&gt;k" type="string" value="gapplication launch org.gnome.Maps %U"/>
      <property name="&lt;Alt&gt;h" type="string" value="xfce4-terminal --maximize --hide-scrollbar -H -x zsh -c &quot; htop&quot;"/>
      <property name="Super_L" type="string" value="/usr/bin/xfce4-popup-whiskermenu"/>
      <property name="&lt;Alt&gt;j" type="string" value="env DESKTOPINTEGRATION=0 APPIMAGELAUNCHER_DISABLE=1 /usr/bin/joplin-desktop --no-sandbox %U"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;t" type="string" value="exo-open --launch TerminalEmulator --hide-menubar --hide-toolbar --geometry 85x18"/>
      <property name="&lt;Alt&gt;t" type="string" value="exo-open --launch MailReader"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;f" type="string" value="exo-open --launch FileManager"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;x" type="string" value="xkill"/>
    </property>
  </property>
  <property name="xfwm4" type="empty">
    <property name="default" type="empty">
      <property name="&lt;Alt&gt;Insert" type="empty"/>
      <property name="Escape" type="empty"/>
      <property name="Left" type="empty"/>
      <property name="Right" type="empty"/>
      <property name="Up" type="empty"/>
      <property name="Down" type="empty"/>
      <property name="&lt;Alt&gt;Tab" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Shift&gt;Tab" type="empty"/>
      <property name="&lt;Alt&gt;Delete" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;Down" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;Left" type="empty"/>
      <property name="&lt;Shift&gt;&lt;Alt&gt;Page_Down" type="empty"/>
      <property name="&lt;Alt&gt;F4" type="empty"/>
      <property name="&lt;Alt&gt;F6" type="empty"/>
      <property name="&lt;Alt&gt;F7" type="empty"/>
      <property name="&lt;Alt&gt;F8" type="empty"/>
      <property name="&lt;Alt&gt;F9" type="empty"/>
      <property name="&lt;Alt&gt;F10" type="empty"/>
      <property name="&lt;Alt&gt;F11" type="empty"/>
      <property name="&lt;Alt&gt;F12" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Shift&gt;&lt;Alt&gt;Left" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;End" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;Home" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Shift&gt;&lt;Alt&gt;Right" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Shift&gt;&lt;Alt&gt;Up" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;KP_1" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;KP_2" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;KP_3" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;KP_4" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;KP_5" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;KP_6" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;KP_7" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;KP_8" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;KP_9" type="empty"/>
      <property name="&lt;Alt&gt;space" type="empty"/>
      <property name="&lt;Shift&gt;&lt;Alt&gt;Page_Up" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;Right" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;d" type="empty"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;Up" type="empty"/>
      <property name="&lt;Super&gt;Tab" type="empty"/>
      <property name="&lt;Primary&gt;F1" type="empty"/>
      <property name="&lt;Primary&gt;F2" type="empty"/>
      <property name="&lt;Primary&gt;F3" type="empty"/>
      <property name="&lt;Primary&gt;F4" type="empty"/>
      <property name="&lt;Primary&gt;F5" type="empty"/>
      <property name="&lt;Primary&gt;F6" type="empty"/>
      <property name="&lt;Primary&gt;F7" type="empty"/>
      <property name="&lt;Primary&gt;F8" type="empty"/>
      <property name="&lt;Primary&gt;F9" type="empty"/>
      <property name="&lt;Primary&gt;F10" type="empty"/>
      <property name="&lt;Primary&gt;F11" type="empty"/>
      <property name="&lt;Primary&gt;F12" type="empty"/>
      <property name="&lt;Super&gt;KP_Left" type="empty"/>
      <property name="&lt;Super&gt;KP_Right" type="empty"/>
      <property name="&lt;Super&gt;KP_Down" type="empty"/>
      <property name="&lt;Super&gt;KP_Up" type="empty"/>
      <property name="&lt;Super&gt;KP_Page_Up" type="empty"/>
      <property name="&lt;Super&gt;KP_Home" type="empty"/>
      <property name="&lt;Super&gt;KP_End" type="empty"/>
      <property name="&lt;Super&gt;KP_Next" type="empty"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Down" type="empty"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Left" type="empty"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Left" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;End" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;Home" type="empty"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Right" type="empty"/>
      <property name="&lt;Control&gt;&lt;Shift&gt;&lt;Alt&gt;Up" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_1" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_2" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_3" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_4" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_5" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_6" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_7" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_8" type="empty"/>
      <property name="&lt;Alt&gt;&lt;Control&gt;KP_9" type="empty"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Right" type="empty"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;d" type="empty"/>
      <property name="&lt;Control&gt;&lt;Alt&gt;Up" type="empty"/>
      <property name="&lt;Control&gt;F1" type="empty"/>
      <property name="&lt;Control&gt;F2" type="empty"/>
      <property name="&lt;Control&gt;F3" type="empty"/>
      <property name="&lt;Control&gt;F4" type="empty"/>
      <property name="&lt;Control&gt;F5" type="empty"/>
      <property name="&lt;Control&gt;F6" type="empty"/>
      <property name="&lt;Control&gt;F7" type="empty"/>
      <property name="&lt;Control&gt;F8" type="empty"/>
      <property name="&lt;Control&gt;F9" type="empty"/>
      <property name="&lt;Control&gt;F10" type="empty"/>
      <property name="&lt;Control&gt;F11" type="empty"/>
      <property name="&lt;Control&gt;F12" type="empty"/>
      <property name="&lt;Shift&gt;&lt;Control&gt;&lt;Alt&gt;Up" type="string" value="move_window_up_workspace_key"/>
      <property name="&lt;Shift&gt;&lt;Control&gt;&lt;Alt&gt;Down" type="string" value="move_window_down_workspace_key"/>
      <property name="&lt;Shift&gt;&lt;Control&gt;&lt;Alt&gt;Left" type="string" value="move_window_left_workspace_key"/>
      <property name="&lt;Shift&gt;&lt;Control&gt;&lt;Alt&gt;Right" type="string" value="move_window_right_workspace_key"/>
    </property>
    <property name="custom" type="empty">
      <property name="&lt;Alt&gt;&lt;Shift&gt;Tab" type="string" value="cycle_reverse_windows_key"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;KP_1" type="string" value="move_window_workspace_1_key"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;KP_2" type="string" value="move_window_workspace_2_key"/>
      <property name="&lt;Super&gt;Tab" type="string" value="switch_window_key"/>
      <property name="&lt;Primary&gt;F1" type="string" value="workspace_1_key"/>
      <property name="Right" type="string" value="right_key"/>
      <property name="Left" type="string" value="left_key"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;d" type="string" value="show_desktop_key"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;KP_3" type="string" value="move_window_workspace_3_key"/>
      <property name="Up" type="string" value="up_key"/>
      <property name="&lt;Primary&gt;F2" type="string" value="workspace_2_key"/>
      <property name="Down" type="string" value="down_key"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;KP_4" type="string" value="move_window_workspace_4_key"/>
      <property name="&lt;Primary&gt;F3" type="string" value="workspace_3_key"/>
      <property name="&lt;Shift&gt;&lt;Control&gt;&lt;Alt&gt;Left" type="string" value="move_window_left_workspace_key"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;Down" type="string" value="down_workspace_key"/>
      <property name="&lt;Shift&gt;&lt;Control&gt;&lt;Alt&gt;Right" type="string" value="move_window_right_workspace_key"/>
      <property name="&lt;Shift&gt;&lt;Control&gt;&lt;Alt&gt;Down" type="string" value="move_window_down_workspace_key"/>
      <property name="&lt;Primary&gt;F4" type="string" value="workspace_4_key"/>
      <property name="&lt;Alt&gt;Insert" type="string" value="add_workspace_key"/>
      <property name="Escape" type="string" value="cancel_key"/>
      <property name="&lt;Primary&gt;&lt;Shift&gt;&lt;Alt&gt;Up" type="string" value="move_window_up_key"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;Up" type="string" value="up_workspace_key"/>
      <property name="&lt;Shift&gt;&lt;Control&gt;&lt;Alt&gt;Up" type="string" value="move_window_up_workspace_key"/>
      <property name="&lt;Alt&gt;F4" type="string" value="close_window_key"/>
      <property name="&lt;Alt&gt;Delete" type="string" value="del_workspace_key"/>
      <property name="&lt;Alt&gt;Tab" type="string" value="cycle_windows_key"/>
      <property name="&lt;Alt&gt;space" type="string" value="popup_menu_key"/>
      <property name="override" type="bool" value="true"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;Left" type="string" value="prev_workspace_key"/>
      <property name="&lt;Primary&gt;&lt;Alt&gt;Right" type="string" value="next_workspace_key"/>
      <property name="&lt;Primary&gt;&lt;Shift&gt;&lt;Alt&gt;Left" type="string" value="move_window_prev_workspace_key"/>
      <property name="&lt;Primary&gt;&lt;Shift&gt;&lt;Alt&gt;Right" type="string" value="move_window_next_workspace_key"/>
    </property>
  </property>
  <property name="providers" type="array">
    <value type="string" value="xfwm4"/>
    <value type="string" value="commands"/>
  </property>
</channel>

…And yes, that was a mess…
It leads to an infinity loop with no exit. —> tty and reboot…

so I change up the script with a counter.

~/.local/bin/magickeys.sh
#!/usr/bin/env bash

i=0

# while [ $i -lt 11 ]; do

#     xdotool key 1
#     xdotool key 2
#     xdotool key 3
#     xdotool key 4
#     sleep 0.4
#     i=$((i + 1))
# done

# --------------------------------------

PIDS=$(pidof -o $$ -x poll.sh)

if [ x"$PIDS" != x ]; then
    pkill -s SIGTERM "$PIDS"
else
    while [ $i -lt 6 ]; do
        xdotool key 1
        xdotool key 2
        xdotool key 3
        xdotool key 4
        sleep 0.4
        i=$((i + 1))
    done
fi

So now I can already see a better us case by setting the counter accordantly, if the toggle version does not work.

also sadly I don’t see a different between does two version in magickeys.ch

also a problem apear by chaning the keybind § in the keyboard setting, leads to a broken w key. I can’t figure out why.

then I also found autokey in the AUR
with no broken w key. but there I also could not figure out a toggle option jet, I guess retCode=() has to set accordendly…
the macro file from autokey is in python.

import time

while True:
    retCode = keyboard.wait_for_keypress(
   'c', modifiers=['<ctrl>'], timeOut= 0.4)
    if retCode:
        break
    keyboard.send_key("1")
    keyboard.send_key("2")
    keyboard.send_key("3")
    keyboard.send_key("4")
    # time.sleep(0.4)

I accidentally left the test file name there (poll.sh) … sorry, try again, noting the correct filename.

That did not work.

Autokey modification
# import os
import time
# import keyboard

i = 0

# while True:
while i < 11:
    retCode = keyboard.wait_for_keypress(
    'q', timeOut= 0.4)
    if retCode:
        break
    keyboard.send_key("1")
    keyboard.send_key("2")
    keyboard.send_key("3")
    keyboard.send_key("4")
    # time.sleep(0.4)
    i += 1

Well … I thought the point was to have it continuously go over the loop until you run the script (press the key) again.

It worked here.

But now you are doing something else with autokey.
I dont know much about that … have at their docs I guess.

The process doesn’t get killed for me, it just spawns more processes. This works:

~/.local/bin/magickeys.sh

#!/usr/bin/env bash

PIDS=$(pgrep -Af magickeys.sh)

if [ x$PIDS != x ]
   then kill -s SIGTERM $PIDS
   else while true; do
      xdotool key 1
      xdotool key 2
      xdotool key 3
      xdotool key 4
      sleep 0.4
   done
fi

@terashy88

This was done with the above script bound to a key: 123412341234

If you want something else then please explain.