xkeysnail is yet another keyboard remapping tool for X environment written in Python

Overview

xkeysnail

xkeysnail is yet another keyboard remapping tool for X environment written in Python. It's like xmodmap but allows more flexible remappings.

screenshot

  • Pros
    • Has high-level and flexible remapping mechanisms, such as
      • per-application keybindings can be defined
      • multiple stroke keybindings can be defined such as Ctrl+x Ctrl+c to Ctrl+q
      • not only key remapping but arbitrary commands defined by Python can be bound to a key
    • Runs in low-level layer (evdev and uinput), making remapping work in almost all the places
  • Cons
    • Runs in root-mode (requires sudo)

The key remapping mechanism of xkeysnail is based on pykeymacs (https://github.com/DreaminginCodeZH/pykeymacs).

Installation

Requires root privilege and Python 3.

Ubuntu

sudo apt install python3-pip
sudo pip3 install xkeysnail

# If you plan to compile from source
sudo apt install python3-dev

Fedora

sudo dnf install python3-pip
sudo pip3 install xkeysnail
# Add your user to input group if you don't want to run xkeysnail
# with sudo (log out and log in again to apply group change)
sudo usermod -a -G input $USER

# If you plan to compile from source
sudo dnf install python3-devel

Manjaro/Arch

# Some distros will need to compile evdev components 
# and may fail to do so if gcc is not installed.
sudo pacman -Syy
sudo pacman -S gcc

Solus

# Some distros will need to compile evdev components 
# and may fail to do so if gcc is not installed.
sudo eopkg install gcc
sudo eopkg install -c system.devel

From source

git clone --depth 1 https://github.com/mooz/xkeysnail.git
cd xkeysnail
sudo pip3 install --upgrade .

Usage

sudo xkeysnail config.py

When you encounter the errors like Xlib.error.DisplayConnectionError: Can't connect to display ":0.0": b'No protocol specified\n' , try

xhost +SI:localuser:root
sudo xkeysnail config.py

If you want to specify keyboard devices, use --devices option:

sudo xkeysnail config.py --devices /dev/input/event3 'Topre Corporation HHKB Professional'

If you have hot-plugging keyboards, use --watch option.

If you want to suppress output of key events, use -q / --quiet option especially when running as a daemon.

How to prepare config.py?

(If you just need Emacs-like keybindings, consider to use example/config.py, which contains Emacs-like keybindings).

Configuration file is a Python script that consists of several keymaps defined by define_keymap(condition, mappings, name)

define_keymap(condition, mappings, name)

Defines a keymap consists of mappings, which is activated when the condition is satisfied.

Argument condition specifies the condition of activating the mappings on an application and takes one of the following forms:

  • Regular expression (e.g., re.compile("YYY"))
    • Activates the mappings if the pattern YYY matches the WM_CLASS of the application.
    • Case Insensitivity matching against WM_CLASS via re.IGNORECASE (e.g. re.compile('Gnome-terminal', re.IGNORECASE))
  • lambda wm_class: some_condition(wm_class)
    • Activates the mappings if the WM_CLASS of the application satisfies the condition specified by the lambda function.
    • Case Insensitivity matching via casefold() or lambda wm_class: wm_class.casefold() (see example below to see how to compare to a list of names)
  • None: Refers to no condition. None-specified keymap will be a global keymap and is always enabled.

Argument mappings is a dictionary in the form of {key: command, key2: command2, ...} where key and command take following forms:

  • key: Key to override specified by K("YYY")
  • command: one of the followings
    • K("YYY"): Dispatch custom key to the application.
    • [command1, command2, ...]: Execute commands sequentially.
    • { ... }: Sub-keymap. Used to define multiple stroke keybindings. See multiple stroke keys for details.
    • pass_through_key: Pass through key to the application. Useful to override the global mappings behavior on certain applications.
    • escape_next_key: Escape next key.
    • Arbitrary function: The function is executed and the returned value is used as a command.
      • Can be used to invoke UNIX commands.

Argument name specifies the keymap name. This is an optional argument.

Key Specification

Key specification in a keymap is in a form of K("( -)* ") where

is one of the followings

  • C or Ctrl -> Control key
  • M or Alt -> Alt key
  • Shift -> Shift key
  • Super or Win -> Super/Windows key

You can specify left/right modifiers by adding any one of prefixes L/R.

And is a key whose name is defined in key.py.

Here is a list of key specification examples:

  • K("C-M-j"): Ctrl + Alt + j
  • K("Ctrl-m"): Ctrl + m
  • K("Win-o"): Super/Windows + o
  • K("M-Shift-comma"): Alt + Shift + comma (= Alt + >)

Multiple stroke keys

When you needs multiple stroke keys, define nested keymap. For example, the following example remaps C-x C-c to C-q.

define_keymap(None, {
    K("C-x"): {
      K("C-c"): K("C-q"),
      K("C-f"): K("C-q"),
    }
})

Checking an application's WM_CLASS with xprop

To check WM_CLASS of the application you want to have custom keymap, use xprop command:

xprop WM_CLASS

and then click the application. xprop tells WM_CLASS of the application as follows.

WM_CLASS(STRING) = "Navigator", "Firefox"

Use the second value (in this case Firefox) as the WM_CLASS value in your config.py.

Example config.py

See example/config.py.

Here is an excerpt of example/config.py.

from xkeysnail.transform import *

define_keymap(re.compile("Firefox|Google-chrome"), {
    # Ctrl+Alt+j/k to switch next/previous tab
    K("C-M-j"): K("C-TAB"),
    K("C-M-k"): K("C-Shift-TAB"),
}, "Firefox and Chrome")

define_keymap(re.compile("Zeal"), {
    # Ctrl+s to focus search area
    K("C-s"): K("C-k"),
}, "Zeal")

define_keymap(lambda wm_class: wm_class not in ("Emacs", "URxvt"), {
    # Cancel
    K("C-g"): [K("esc"), set_mark(False)],
    # Escape
    K("C-q"): escape_next_key,
    # C-x YYY
    K("C-x"): {
        # C-x h (select all)
        K("h"): [K("C-home"), K("C-a"), set_mark(True)],
        # C-x C-f (open)
        K("C-f"): K("C-o"),
        # C-x C-s (save)
        K("C-s"): K("C-s"),
        # C-x k (kill tab)
        K("k"): K("C-f4"),
        # C-x C-c (exit)
        K("C-c"): K("M-f4"),
        # cancel
        K("C-g"): pass_through_key,
        # C-x u (undo)
        K("u"): [K("C-z"), set_mark(False)],
    }
}, "Emacs-like keys")

Example of Case Insensitivity Matching

terminals = ["gnome-terminal","konsole","io.elementary.terminal","sakura"]
terminals = [term.casefold() for term in terminals]
termStr = "|".join(str(x) for x in terminals)

# [Conditional modmap] Change modifier keys in certain applications
define_conditional_modmap(lambda wm_class: wm_class.casefold() not in terminals,{
    # Default Mac/Win
    Key.LEFT_ALT: Key.RIGHT_CTRL,   # WinMac
    Key.LEFT_META: Key.LEFT_ALT,    # WinMac
    Key.LEFT_CTRL: Key.LEFT_META,   # WinMac
    Key.RIGHT_ALT: Key.RIGHT_CTRL,  # WinMac
    Key.RIGHT_META: Key.RIGHT_ALT,  # WinMac
    Key.RIGHT_CTRL: Key.RIGHT_META, # WinMac
})

# [Conditional modmap] Change modifier keys in certain applications
define_conditional_modmap(re.compile(termStr, re.IGNORECASE), {

    # Default Mac/Win
    Key.LEFT_ALT: Key.RIGHT_CTRL,   # WinMac
    Key.LEFT_META: Key.LEFT_ALT,    # WinMac
    Key.LEFT_CTRL: Key.LEFT_CTRL,   # WinMac
    Key.RIGHT_ALT: Key.RIGHT_CTRL,  # WinMac
    Key.RIGHT_META: Key.RIGHT_ALT,  # WinMac
    Key.RIGHT_CTRL: Key.LEFT_CTRL,  # WinMac
})

FAQ

How do I fix Firefox capturing Alt before xkeysnail?

In the Firefox location bar, go to about:config, search for ui.key.menuAccessKeyFocuses, and set the Value to false.

License

xkeysnail is distributed under GPL.

xkeysnail
Copyright (C) 2018 Masafumi Oyamada

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see 
   
   .

xkeysnail is based on pykeymacs (https://github.com/DreaminginCodeZH/pykeymacs), which is distributed under GPL.

pykeymacs
Copyright (C) 2015 Zhang Hai

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see 
   
   .
Owner
Masafumi Oyamada
Masafumi Oyamada
NS-Defacer: a auto html injecter, In other words It's a auto defacer to deface a lot of websites in less time

Overview NS-Defacer is a auto html injecter, In other words It's a auto defacer

NightSec 10 Nov 19, 2022
macOS Initial Access Payload Generator

Mystikal macOS Initial Access Payload Generator Related Blog Post: https://posts.specterops.io/introducing-mystikal-4fbd2f7ae520 Usage: Install Xcode

Leo Pitt 206 Dec 31, 2022
Pgen is the best brute force password generator and it is improved from the cupp.py

pgen Pgen is the best brute force password generator and it is improved from the cupp.py The pgen tool is dedicated to Leonardo da Vinci -Time stays l

heyheykids 2 Jan 31, 2022
Sudo Baron Samedit Exploit

CVE-2021-3156 (Sudo Baron Samedit) This repository is CVE-2021-3156 exploit targeting Linux x64. For writeup, please visit https://datafarm-cybersecur

Worawit Wang 559 Jan 03, 2023
Security System using OpenCV

Security-System Security System using OpenCV Files in this Repository: email_send.py - This file contains python code to send an email when something

Mehul Patwari 1 Oct 28, 2021
CVE-2022-21907 Vulnerability PoC

CVE-2022-21907 Description POC for CVE-2022-21907: HTTP Protocol Stack Remote Code Execution Vulnerability. create by antx at 2022-01-17, just some sm

Michele 16 Dec 18, 2022
Pupy is an opensource, cross-platform (Windows, Linux, OSX, Android) remote administration and post-exploitation tool mainly written in python

Pupy Installation Installation instructions are on the wiki, in addition to all other documentation. For maximum compatibility, it is recommended to u

7.4k Jan 04, 2023
HTTP Protocol Stack Remote Code Execution Vulnerability CVE-2022-21907

CVE-2022-21907 Description POC for CVE-2022-21907: HTTP Protocol Stack Remote Code Execution Vulnerability. create by antx at 2022-01-17. Detail HTTP

赛欧思网络安全研究实验室 365 Nov 30, 2022
The probability of having the password you want in the PassMaker is +90%!!

PasswordMaker Strong listing password Introduction The probability of having the password you want in the tool is +90%!! How to Install Open the termi

MasterBurnt 4 Sep 05, 2021
This is a Crypto asset tracker that I built to aid my personal journey in cryptocurrencies.

Wallet Tracker This is a Crypto asset tracker that I built to aid my personal journey in cryptocurrencies. build docker build -t wallet-tracker . run

2 Mar 21, 2022
Domain abuse scanner covering domainsquatting and phishing keywords.

🦷 monodon 🐋 Domain abuse scanner covering domainsquatting and phishing keywords. Setup Monodon is a Python 3.7+ programm. To setup on a Linux machin

2 Mar 15, 2022
SpiderFoot automates OSINT collection so that you can focus on analysis.

SpiderFoot is an open source intelligence (OSINT) automation tool. It integrates with just about every data source available and utilises a range of m

Steve Micallef 9k Jan 08, 2023
Malware Configuration And Payload Extraction

CAPEv2 (Python3) has now been released CAPEv2 With the imminent end-of-life for Python 2 (January 1 2020), CAPEv1 will be phased out. Please upgrade t

Context Information Security 701 Dec 27, 2022
Open Source Intelligence gathering tool aimed at reducing the time spent harvesting information from open sources.

The Recon-ng Framework Recon-ng content now available on Pluralsight! Recon-ng is a full-featured reconnaissance framework designed with the goal of p

2.4k Jan 07, 2023
Generate MIPS reverse shell shellcodes easily !

MIPS-Reverse MIPS-Reverse is a tool that can generate shellcodes for the MIPS architecture that launches a reverse shell where you can specify the IP

29 Jul 27, 2021
DoSer.py - Simple DoSer in Python

DoSer.py - Simple DoSer in Python What is DoSer? DoSer is basically an HTTP Denial of Service attack that affects threaded servers. It works like this

1 Oct 12, 2021
domato but as a website

ROFL-FUZZER Ths is Domato, a DOM Fuzzer from Google, but hosted as an website It generates a instance of a newtab on the template given by the user ,

Swapnadeep Som 18 Nov 22, 2021
Fast Fb Cracking Tool

fb-brute Fast Fb Cracking Tool 🏆

Aryan 8 Jun 29, 2022
A simple way to store your passwords without requiring third party applications

SimplePasswordManager A simple way to store your passwords without requiring third party applications Simple To Use. Store Your Passwords For Each Web

Leone Odinga 1 Dec 23, 2021
A python module for retrieving and parsing WHOIS data

pythonwhois A WHOIS retrieval and parsing library for Python. Dependencies None! All you need is the Python standard library. Instructions The manual

Sven Slootweg 384 Dec 23, 2022