Application-specific key combination remapping?

8,529

Solution 1

Your idea of using xbindkeys sounds good:

in your .xbindkeysrc add a new keybinding:

"app_specific_keys.sh"
   Control+s

This will execute "app_specific_keys.sh" when you press ctrl+s.

Now you need to define the script. It should get the active window and from that the name of the app which currently has the focus:

xprop -id `xdotool getactivewindow` |awk '/WM_CLASS/{print $4}'

This would do the trick: it asks xdotool for the active window, then asks xprop for all properties of the window with the given id, and then reduces the very verbose output to the name of the application (actually its class). If you run this in a gnome-terminal you would get

"Gnome-terminal"

Now you need to define actions for your applications:

if [ $N = '"Gnome-terminal"' ]; then                                                    
    xdotool key --clearmodifiers ctrl+s                                                          
else                                                                            
    xdotool key --clearmodifiers ctrl+d                                                          
fi  

So together, the script "app_specific_keys.sh" could look like this:

#!/bin/bash                                                                     
W=`xdotool getactivewindow`                                                     
S1=`xprop -id ${W} |awk '/WM_CLASS/{print $4}'`                                 
S2='"Gnome-terminal"'                                                           
if [ $S1 = $S2 ]; then                                                          
   xdotool key --clearmodifiers ctrl+d                                             
else                                                                            
   xdotool key --clearmodifiers ctrl+s                                          
fi  

This should work, but as in this question, I have to admit that it does not. Probably because one of Compiz, Unity, Global Menu does not work well with the --clearmodifiers option of xdotool. A workaround would be to add a sleep in front of your script in oder to be able to release the keys yourself: In your .xbindkeysrc change to this keybinding:

"sleep 0.5; app_specific_keys.sh"
   Control+s

As a sidenote: this will not work, if you want to change keys for programs which run in a terminal (e.g. vi or emacs in console mode). The returned application class would still be "Gnome-terminal".

Hope that helps.

Solution 2

autokey is like AutoHotkey for Ubuntu. You can write scripts in python and have them execute via keyboard shortcut and a windows filter (making it pseudo-application specific). Your script can control keyboard and mouse events and even move windows around as an added touch.

Share:
8,529

Related videos on Youtube

Derek Thurn
Author by

Derek Thurn

Updated on September 18, 2022

Comments

  • Derek Thurn
    Derek Thurn over 1 year

    I'm aware of a number of ways of remapping key combinations in Ubuntu on a global basis (e.g., globally remapping Ctrl+S to send Ctrl+D or something), such as the xbindkeys application. What I need, though, is a way to do this only for a specific application. For example, something like "Remap Ctrl+S to send Ctrl+D, but only in Chrome". Is there any way to accomplish this?

    • lumbric
      lumbric over 12 years
      Did you read this thread? I haven't tried it, but it seems to me to be exanctly what you are searching for. I don't know engouh about it to write a proper answer, though.
  • Derek Thurn
    Derek Thurn about 12 years
    This ended up working just fine. I didn't use xdotool to send the keystrokes, I just used xvkbd -xsendevent -text "\Cs". This doesn't seem to suffer from the issues you were seeing with xdotool.
  • phil294
    phil294 about 8 years
    it's not possible to make a key call itself, like f calling xdotool key f. Still searching for a way to do this.
  • phil294
    phil294 about 8 years
    ha, finally found one! xdotool type --window $(xdotool getwindowfocus) [keys] using the --window option and sending to the currently active window will NOT lead to recursive behaviour.