How to remap a key when it's pressed twice?
Some of my keyboard keys has gone, so I’m trying to program the other keys that are still working to press the damaged keys when I press them twice. Is that possible? Is there any program that can help me in doing that?
I want to remap the key J to give 'm' when I press it twice.
NB: My laptop is a MacBook Pro 13" Unibody Mid 2012
Solution 1:
Set aliases for characters, strings or complete lines
UNLESS you are using wayland (Ubuntu 17.10, tested on Ubuntu Budgie 18.04, but Ubuntu Gnome 18.04 should be fine too), the snippet below will help you out.
How it works in practice
- Press Ctrl + J (or any other shortcut you set)
-
A box appears
Type your "alias" (e.g. jj for m), the result shows (m), and the text will immediately be inserted at cursor position (or, if you prefer, after tapping Ctrl).
This script provides a single solution to set aliasses for a character, a string or even complete lines, just set the "alias" in the lines:
replacements = [
["jj", "m"],
["aa", "q"],
["zz", "e"],
["mb", "monkey eats banana"],
]
In the latter case, typing "mb" will paste "monkey eats banana":
Setting up
-
You need to satisfy a few dependencies:
-
pyautogui:
pip3 install pyautogui
-
pyperclip:
sudo apt install python3-pyperclip xsel xclip
-
python3-xlib
sudo apt install python3-xlib
Log out and back in.
-
-
Copy the script below into an empty file, save it as
replace_keys.py
#!/usr/bin/env python3 import gi gi.require_version("Gtk", "3.0") gi.require_version("Wnck", "3.0") from gi.repository import Gtk, Gdk, Wnck import subprocess import pyperclip import pyautogui import time """ depends on - pyautogui: pip3 install pyautogui - pyperclip: sudo apt install python3-pyperclip xsel xclip """ act_on_firstmatch = False replacements = [ ["jj", "m"], ["aa", "q"], ["zz", "e"], ["mb", "monkey eats banana"], ] class KeyWin(Gtk.Window): def __init__(self): self.screendata = Wnck.Screen.get_default() self.screendata.force_update() self.curr_subject = self.screendata.get_active_window().get_xid() self.currmatch = "" Gtk.Window.__init__(self) maingrid = Gtk.Grid() self.add(maingrid) self.set_decorated(False) self.set_position(Gtk.WindowPosition.CENTER) self.connect("key-release-event", self.check_key) self.keyentry = Gtk.Entry() self.keyentry.connect("changed", self.update_current) self.label = Gtk.Label("") self.label.set_width_chars(10) maingrid.attach(self.keyentry, 0, 0, 1, 1) maingrid.attach(self.label, 1, 0, 1, 1) self.show_all() self.connect("destroy", Gtk.main_quit) Gtk.main() def update_current(self, widget): curr = self.keyentry.get_text() self.currmatch = "" for s in replacements: if curr == s[0]: self.currmatch = s[1] if act_on_firstmatch: self.replace() self.label.set_width_chars(len(self.currmatch) + 4) self.label.set_text(self.currmatch) def replace(self, *args): pyperclip.copy(self.currmatch) subprocess.call(["wmctrl", "-ia", str(self.curr_subject)]) Gtk.main_quit() def check_key(self, button, val): typed = Gdk.keyval_name(val.keyval) if typed == "Control_L": self.replace() KeyWin() time.sleep(0.05) pyautogui.hotkey('ctrl', 'v')
-
Set up your aliasses (KEEP THE INDENTATION!) in the section:
replacements = [ ["jj", "m"], ["aa", "q"], ["zz", "e"], ["mb", "monkey eats banana"], ]
-
If you want, change
act_on_firstmatch = False
into
act_on_firstmatch = True
if you like to insert immediately without tapping Ctrl
-
Set up a shortcut key with Ctrl as modifier. I used Ctrl + J in my test to run the script by the command:
python3 /path/to/replace_keys.py
And you're done!