Como definir o atalho AutoKey que envia o mesmo toque de tecla para a janela com determinado título

6

Como definir um atalho global Ctrl + a 1 com AutoKey que envia o mesmo pressionamento de tecla Ctrl + a 1 para a janela com o título 'gnu screen'? Se não houver essa janela de título, ela deverá mostrar uma mensagem pop-up "Não foi possível encontrar a janela de destino".

    
por zuba 30.05.2015 / 12:53

3 respostas

2

  1. Instale o libnotify-bin, que fornece o comando notify-send

    sudo apt-get install libnotify-bin
    
  2. Crie um novo 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"])
    
  3. Configure sua tecla de atalho como: Ctrl + a

Para acionar: Ctrl + a e 1 (em & lt; 1seg)

Depurar

  1. Inicie o X Event Tester na janela do terminal separada

    xev -event keyboard
    
  2. Verifique o título da janela, o meu mostra 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
    
  3. Modifique o script para segmentar a janela Event Tester .

    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")
    
  4. Se xev receber a sequência de teclas. Sua saída deve ser algo semelhante a:

    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 que removi a condição if para verificar o título ativo. O script ativa / aumenta a janela xev, mas a verificação não encontra o título correto. Eu recebi apenas a mensagem de notificação.

    
por user.dz 22.06.2015 / 02:07
1

Eu estava pensando na mesma linha como "Mostafa Najafiyazdi" e usei sua função wmctrl como base para a primeira versão do script da função com algumas modificações.

Isso não é específico do autokey e, como tal, não é um script python. Eu uso uma configuração similar para ativar, alternar e fazer algumas coisas no meu media-pc (mythtv) com um único botão remotecontrol.

A configuração do atalho / autokey do Windows para executar esses scripts com chaves combinadas é difícil e o ctrl + a geralmente é algo globalmente diferente. Se você decidir usar algo ctrl + f7 para a chave de ativação, então, chamar esse script deve fazer o que você quiser.

Isto requer xdotool e libnotify-bin. Isso não alterará a janela ativa para "gnu screen", consulte a seção comentada para alterar a mesma funcionalidade do script activate_window_and_send_keys.

~/bin/focus_window_and_send_keys "gnu screen" "ctrl+a+1"

E o 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"

Minha primeira versão exigia isso e é funcional (abaixo), mas usa wrapper extra e precisa de janela para estar ativa. versão xdotool não requer isso.

Isso requer xautomation libnotify-bin e wmctrl

isto é ~ / bin / activate_window_and_send_keys scipt Para fazer o que você quer do cmdline, você chamaria isso com

# 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"

Lembre-se de chmod u + x nos seus scripts ~ / bin / *

#!/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=
  window_found='wmctrl -l | grep "$title" | awk '{print }''
  # 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
}

Isso é ~ / bin / sendkey É simplesmente um wrapper em torno do xte para simplificar a sintaxe do xte

#!/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");
}
    
por Manwe 23.06.2015 / 11:30
0

A primeira coisa que me vem à mente é quebrar o que você quer fazer em duas partes:

  1. Escrevendo uma função bash que verifica uma janela intitulada o que você quiser, para você seria 'gnu screen', se não for encontrado, aparecerá uma mensagem dizendo "Não foi possível encontrar a janela de destino!" Para isso, primeiro você precisa instalar o wmctrl

    sudo apt-get install wmctrl
    

    É um controlador do Windows que você pode usar para obter informações sobre janelas, incluindo seu PID, título, posição, tamanho, número da área de trabalho, etc. Adicione o seguinte código em .bash_aliases :

    function find_window {
      # Get the list of all windows 
      # and select the line containing a substring given as 
      # an argument to the script
      title=
    
      window_found='wmctrl -l | grep $title | awk '{print }''
    
      # If nothing is found, echo a message
      if [ -z "$window_found" ]; then
        notify-send -i face-crying "Can't find specified window!"
      else
        wmctrl -a 
      fi
    }
    

    Você pode alterar a aparência da notificação. Basta ver a página de manual para notify-send .

  2. Defina um custom curto usando as configurações do sistema. Veja aqui Simples adicione find_window "gnu screen" como o comando a ser executado. Você define sequências de teclado como quiser.

EDITAR : Se a janela existir, irá mudar para essa janela! Isso é o que o else no if then else faz.

    
por Mostafa Najafiyazdi 18.06.2015 / 07:20