How to define AutoKey shortcut which sends the same keystroke to the window with certain title
-
Install libnotify-bin which provides notify-send
sudo apt-get install libnotify-bin
-
Create new script:
import time import subprocess #no need #keyboard.release_key("<ctrl>") # wait_for_keypress does not return any thing to distinguish between target key pressed or timeout reached. # So if time is less than the timeout then it was key press. start_time = time.time() keyboard.wait_for_keypress("1", timeOut=1) if (time.time()-start_time < 0.9): time.sleep(0.2) window.activate("gnu screen") time.sleep(0.1) active_title = window.get_active_title() # if it doesn't get same title, then no window titled as gnu screen # it sends a notify message otherwise send the key sequence. if (active_title == "gnu screen"): keyboard.press_key("<ctrl>") keyboard.send_key("a") keyboard.release_key("<ctrl>") keyboard.send_key("1") else: subprocess.Popen(['notify-send', "Couldn't find destination window"])
Setup its hot key as: Ctrl+a
To trigger it: Ctrl+a then 1 (in <1sec)
Debug
-
Launch X Event Tester in separate terminal window
xev -event keyboard
-
Check it's window title, mine shows
Event Tester
$ wmctrl -l 0x03000012 -1 N/A Desktop — Plasma 0x030000c1 -1 N/A Desktop — Plasma 0x0300001b -1 N/A Plasma 0x06a00098 0 PC User User - Ask Ubuntu - Mozilla Firefox 0x01a00067 0 N/A user : screen 0x01a000cd 0 N/A user : xev 0x04600001 0 N/A Event Tester 0x01e0015d 0 PC AutoKey
-
Modify script to target
Event Tester
window.import time import subprocess start_time = time.time() keyboard.wait_for_keypress("1", timeOut=1) if (time.time()-start_time < 0.9): time.sleep(0.2) window.activate("Event Tester") time.sleep(0.1) keyboard.press_key("<ctrl>") keyboard.send_key("a") keyboard.release_key("<ctrl>") keyboard.send_key("1")
-
If
xev
receives the key sequence. Its output should be some thing similar to:KeyPress event, serial 34, synthetic NO, window 0x4600001, root 0xb2, subw 0x0, time 55057700, (1053,140), root:(945,303), state 0x0, keycode 105 (keysym 0xffe4, Control_R), same_screen YES, XLookupString gives 0 bytes: XmbLookupString gives 0 bytes: XFilterEvent returns: False KeyPress event, serial 34, synthetic YES, window 0x4600001, root 0xb2, subw 0x0, time 0, (1,1), root:(1,1), state 0x0, keycode 38 (keysym 0x61, a), same_screen YES, XLookupString gives 1 bytes: (61) "a" XmbLookupString gives 1 bytes: (61) "a" XFilterEvent returns: False KeyRelease event, serial 35, synthetic YES, window 0x4600001, root 0xb2, subw 0x0, time 0, (1,1), root:(1,1), state 0x0, keycode 38 (keysym 0x61, a), same_screen YES, XLookupString gives 1 bytes: (61) "a" XFilterEvent returns: False KeyRelease event, serial 35, synthetic NO, window 0x4600001, root 0xb2, subw 0x0, time 55057701, (1053,140), root:(945,303), state 0x4, keycode 105 (keysym 0xffe4, Control_R), same_screen YES, XLookupString gives 0 bytes: XFilterEvent returns: False KeyPress event, serial 35, synthetic YES, window 0x4600001, root 0xb2, subw 0x0, time 0, (1,1), root:(1,1), state 0x0, keycode 10 (keysym 0x31, 1), same_screen YES, XLookupString gives 1 bytes: (31) "1" XmbLookupString gives 1 bytes: (31) "1" XFilterEvent returns: False KeyRelease event, serial 35, synthetic YES, window 0x4600001, root 0xb2, subw 0x0, time 0, (1,1), root:(1,1), state 0x0, keycode 10 (keysym 0x31, 1), same_screen YES, XLookupString gives 1 bytes: (31) "1" XFilterEvent returns: False
Note, I have removed the if
condition to check active title. The script activates/raises xev window but the check doesn't find the correct title. I got just the notification message.
I was thinking along the same lines as "Mostafa Najafiyazdi" and I used his wmctrl function as a base for first script version of the function with some modifications.
This is not autokey specific and as such it's not a python script. I use similar setup to activate, switch and do some stuff on my media-pc (mythtv) with a single remotecontrol button.
Setting windows shortcut/autokey to run these script with combined keys is difficult and ctrl+a is usually globally something different. If you decide to use something ctrl+f7 for the activation key, then calling this script should do what you want.
This requies xdotool and libnotify-bin. This will not change active window to "gnu screen", see commented section to change to the same functionality as with the activate_window_and_send_keys script.
~/bin/focus_window_and_send_keys "gnu screen" "ctrl+a+1"
And the script:
#!/bin/bash
## copy these files to ~/bin = (~ = is your home directory)
### finding window and keys
## requires xdotool
### notify
## libnotify-bin
# Usage:
# ~/bin/focus_window_and_send_keys "window title" "keys" "morekeys" ...
# ~/bin/focus_window_and_send_keys "gnu screen" "ctrl+a+1"
title=${1:-NOT_FOUND_EMPTY_TITLE}
shift
## get current window
CURWIN=$(xdotool getactivewindow)
TARGETWIN=$(xdotool search --name "$title" | head -n 1)
if [ -z $TARGETWIN ]; then
notify-send -i face-crying "Can't find specified window!"
else
## use this to activate window
#xdotool windowactive "$TARGETWIN"
## changes focus, does not change to the window on display
xdotool windowfocus "$TARGETWIN"
## send keys if window was found
for keypress in "$@"
do
xdotool key --window "$TARGETWIN" "$keypress"
done
fi
## comment next line if focus should stay with activated window
xdotool windowfocus "$CURWIN"
My first version required these and is functional (below), but uses extra wrapper and needs window to be active. xdotool version does not require that.
This requires xautomation libnotify-bin and wmctrl
this is ~/bin/activate_window_and_send_keys scipt To do what you want from cmdline, you'd call this with
# this is press ctrl, a, 1, release ctrl
~/bin/activate_window_and_send_keys "gnu screen" "ctrl+a+1"
# this is press ctrl, a, release ctrl, 1
~/bin/activate_window_and_send_keys "gnu screen" "ctrl+a" "1"
Remember to chmod u+x on your ~/bin/* scripts
#!/bin/bash
## copy these files to ~/bin (~ = is your home directory)
### finding window
## requires wmctrl
### notify
## libnotify-bin
### tool to send keypresses
## requires xautomation
# Usage:
# ~/bin/activate_window_and_send_keys "window title" "keys" "morekeys" ...
# ~/bin/activate_window_and_send_keys "gnu screen" "ctrl+a+1"
export PATH=$PATH:~/bin
## helper function to find correct window
## modified version of Mostafa Najafiyazdi answer
## http://askubuntu.com/a/637897/41757
function find_window_and_activate_window {
# Get the list of all windows
# and select the line containing a substring given as
# an argument to the script
title=$1
window_found=`wmctrl -l | grep "$title" | awk '{print $3}'`
# If nothing is found, echo a message
if [ -z "$window_found" ]; then
notify-send -i face-crying "Can't find specified window!"
return -1
else
wmctrl -a "$title"
fi
}
title=${1:-NOT_FOUND_EMPTY_TITLE}
shift
echo "$title"
find_window_and_activate_window "$title" && {
## send keys if window was found
for keypress in "$@"
do
sendkey "$keypress"
done
}
This is ~/bin/sendkey It is simply a wrapper around xte to simplify xte syntax
#!/usr/bin/perl
my @keys=@ARGV;
for my $key (@keys) {
my @keycomb=split(/\+/, $key);
my $k = pop(@keycomb);
#print "$k\n";
my $modup = "";
my $moddown = "";
my $press = " 'key $k' ";
for my $m (@keycomb) {
$m =~ s/ctrl/Control_L/gi;
$m =~ s/alt/Alt_L/gi;
$m =~ s/shift/Shift_L/gi;
$moddown = $moddown.' "keydown '.$m.'"';
$modup = ' "keyup '.$m.'"'.$modup;
}
system("xte $moddown $press $modup");
}